<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  
  <title>Hexo</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta property="og:type" content="website">
<meta property="og:title" content="Hexo">
<meta property="og:url" content="https://goofyer.gitee.io/notes-on-computer-expertise/page/9/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:locale" content="en_US">
<meta property="article:author" content="John Doe">
<meta name="twitter:card" content="summary">
  
    <link rel="alternate" href="/notes-on-computer-expertise/atom.xml" title="Hexo" type="application/atom+xml">
  
  
    <link rel="shortcut icon" href="/notes-on-computer-expertise/favicon.png">
  
  
    
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-source-code-pro@0.0.71/index.min.css">

  
  
<link rel="stylesheet" href="/notes-on-computer-expertise/css/style.css">

  
    
<link rel="stylesheet" href="/notes-on-computer-expertise/fancybox/jquery.fancybox.min.css">

  
<meta name="generator" content="Hexo 5.4.0"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/notes-on-computer-expertise/" id="logo">Hexo</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/notes-on-computer-expertise/">Home</a>
        
          <a class="main-nav-link" href="/notes-on-computer-expertise/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/notes-on-computer-expertise/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="https://goofyer.gitee.io/notes-on-computer-expertise"></form>
      </div>
    </div>
  </div>
</header>

      <div class="outer">
        <section id="main">
  
    <article id="post-Java/第十九章XML" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E4%B9%9D%E7%AB%A0XML/" class="article-date">
  <time class="dt-published" datetime="2021-12-19T17:35:32.287Z" itemprop="datePublished">2021-12-20</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h2 id="第十九章XML"><a href="#第十九章XML" class="headerlink" title="第十九章XML"></a>第十九章XML</h2><h3 id="01-xml-基础"><a href="#01-xml-基础" class="headerlink" title="01 xml_基础"></a>01 xml_基础</h3><ul>
<li><p>概念：Extensible Markup Language 可扩展标记语言</p>
<ul>
<li><ul>
<li>可扩展：标签都是自定义的。 <user>  <student></li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>功能</p>
<ul>
<li><ul>
<li><p>存储数据</p>
<ul>
<li><ol>
<li>配置文件</li>
</ol>
</li>
<li><ol>
<li>在网络中传输</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>xml与html的区别</p>
<ul>
<li><ol>
<li>xml标签都是自定义的，html标签是预定义。</li>
</ol>
</li>
<li><ol>
<li>xml的语法严格，html语法松散</li>
</ol>
</li>
<li><ol>
<li>xml是存储数据的，html是展示数据</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li>w3c：World Wide Web Consortium，万维网联盟</li>
</ul>
</li>
<li><p>语法：</p>
<ul>
<li><ul>
<li><p>基本语法：</p>
<ul>
<li><ol>
<li>xml文档的后缀名 .xml</li>
</ol>
</li>
<li><ol>
<li>xml第一行必须定义为文档声明</li>
</ol>
</li>
<li><ol>
<li>xml文档中有且仅有一个根标签</li>
</ol>
</li>
<li><ol>
<li>属性值必须使用引号(单双都可)引起来</li>
</ol>
</li>
<li><ol>
<li>标签必须正确关闭（单标签，自闭和：<hr/>）</li>
</ol>
</li>
<li><ol>
<li>xml标签名称区分大小写</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>快速入门：代码…        </p>
<ul>
<li>&lt;?xml version=”1.0” encoding=”UTF-8” ?&gt;<!--版本信息1.0--><br><users><!--根标签--><br><user id='1'><!--自己定义的标签，想写啥 就写啥--><br><name>zhangsan</name><br><age>23</age><br><sex>male</sex>
</user><br><user id='2'><br><name>lisi</name><br><age>24</age><br><sex>female</sex>
</user>
</users><!--
检验xml文档的正确性：
xml可以被所有的浏览器所解析，浏览器中有对应的xml解析引擎
将xml拖拽进浏览器，浏览器不报错，则xml书写正确！
-->
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>组成部分</p>
<ul>
<li><ol>
<li><p>文档声明</p>
<ul>
<li><ol>
<li>格式：&lt;?xml 属性列表 ?&gt; （‘?’与‘&lt;’、‘&gt;’之间不能有空格）</li>
</ol>
</li>
<li><ol>
<li><p>属性列表：</p>
<ul>
<li><ul>
<li>version：版本号，必须的属性（xml第1版就是1.0，1.1版本不向下兼容，主流仍为1.0版）</li>
</ul>
</li>
<li><ul>
<li>encoding：编码方式。告知解析引擎 当前文档使用的字符集，默认值：ISO-8859-1</li>
</ul>
</li>
<li><ul>
<li>standalone：是否独立</li>
</ul>
<ul>
<li><ul>
<li>yes：文件独立，不依赖其他文件</li>
</ul>
</li>
<li><ul>
<li>no：文件不独立，依赖其他文件</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>指令(了解)：结合css</p>
<ul>
<li><ul>
<li>&lt;?xml-stylesheet type=”text/css” href=”a.css” ?&gt;</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>标签：标签名称 自定义</p>
<ul>
<li><ul>
<li><p>规则：</p>
<ul>
<li><ul>
<li>名称可以包含字母、数字以及其他的字符 </li>
</ul>
</li>
<li><ul>
<li>名称不能以数字或者标点符号开始 </li>
</ul>
</li>
<li><ul>
<li>名称不能以字母 xml（或者 XML、Xml 等等）开始 </li>
</ul>
</li>
<li><ul>
<li>名称不能包含空格 </li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>属性：</p>
<ul>
<li><ul>
<li>由键值对构成，用引号（单双引号）引起来</li>
</ul>
</li>
<li><ul>
<li>id属性值唯一</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>文本：</p>
<ul>
<li><ul>
<li>CDATA区：在该区域中的数据会被原样展示</li>
</ul>
</li>
<li><ul>
<li>格式：  &lt;![CDATA[ 数据 ]]&gt;</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="02-xml-约束"><a href="#02-xml-约束" class="headerlink" title="02 xml_约束"></a>02 xml_约束</h3><ul>
<li><p>xml_约束概述</p>
<ul>
<li><ul>
<li>约束：规定xml文档的书写规则</li>
</ul>
</li>
<li><ul>
<li><p>作为框架的使用者(程序员)：</p>
<ul>
<li><ol>
<li>能够在xml中引入约束文档</li>
</ol>
</li>
<li><ol>
<li>能够简单的读懂约束文档</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>分类：</p>
<ul>
<li><ol>
<li><p>DTD：一种简单的约束技术。</p>
<ul>
<li><ul>
<li><p>引入dtd文档到xml文档中</p>
<ul>
<li><ul>
<li>内部dtd：将约束规则定义在xml文档中</li>
</ul>
</li>
<li><ul>
<li><p>外部dtd：将约束的规则定义在外部的dtd文件中</p>
<ul>
<li><ul>
<li>本地：&lt;!DOCTYPE 根标签名 SYSTEM “dtd文件的位置”&gt; ：SYSTEM表示系统本地</li>
</ul>
</li>
<li><ul>
<li>网络：&lt;!DOCTYPE 根标签名 PUBLIC “dtd文件名字” “dtd文件的位置URL”&gt;</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>Schema：一种复杂的约束技术。</p>
<ul>
<li><ul>
<li>引入：</li>
</ul>
</li>
<li>1.填写xml文档的根元素</li>
<li>2.引入xsi前缀.  xmlns:xsi=”<a target="_blank" rel="noopener" href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>“</li>
<li>3.引入xsd文件命名空间. xsi:schemaLocation=”<a target="_blank" rel="noopener" href="http://www.itcast.cn/xml">http://www.itcast.cn/xml</a> student.xsd”</li>
<li><p>4.为每一个xsd约束声明一个前缀,作为标识  xmlns=”<a target="_blank" rel="noopener" href="http://www.itcast.cn/xml">http://www.itcast.cn/xml</a>“ </p>
<ul>
<li><students   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.itcast.cn/xml"
xsi:schemaLocation="http://www.itcast.cn/xml  student.xsd"
><student number="heima_0001">
<name>tom</name>
<age>18</age>
<sex>male</sex>
</student>

</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>&lt;/students&gt;<br>student.xsd<br>&lt;?xml version=”1.0”?&gt;</p>
<p><xsd:schema xmlns="http://www.itcast.cn/xml"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.itcast.cn/xml" elementFormDefault="qualified"><br>    <xsd:element name="students" type="studentsType"/><br>    <xsd:complexType name="studentsType"><br>        <xsd:sequence><br>            <xsd:element name="student" type="studentType" minOccurs="0" maxOccurs="unbounded"/><br>        &lt;/xsd:sequence&gt;<br>    &lt;/xsd:complexType&gt;<br>    <xsd:complexType name="studentType"><br>        <xsd:sequence><br>            <xsd:element name="name" type="xsd:string"/><br>            <xsd:element name="age" type="ageType" /><br>            <xsd:element name="sex" type="sexType" /><br>        &lt;/xsd:sequence&gt;<br>        <xsd:attribute name="number" type="numberType" use="required"/><br>    &lt;/xsd:complexType&gt;<br>    <xsd:simpleType name="sexType"><br>        <xsd:restriction base="xsd:string"><br>            <xsd:enumeration value="male"/><br>            <xsd:enumeration value="female"/><br>        &lt;/xsd:restriction&gt;<br>    &lt;/xsd:simpleType&gt;<br>    <xsd:simpleType name="ageType"><br>        <xsd:restriction base="xsd:integer"><br>            <xsd:minInclusive value="0"/><br>            <xsd:maxInclusive value="256"/><br>        &lt;/xsd:restriction&gt;<br>    &lt;/xsd:simpleType&gt;<br>    <xsd:simpleType name="numberType"><br>        <xsd:restriction base="xsd:string"><br>            <xsd:pattern value="heima_\d{4}"/><br>        &lt;/xsd:restriction&gt;<br>    &lt;/xsd:simpleType&gt;<br>&lt;/xsd:schema&gt;<br>application_mvc.xml<br>&lt;?xml version=”1.0” encoding=”UTF-8”?&gt;</p>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">


<pre><code>&lt;context:annotation-config /&gt;


&lt;context:component-scan base-package=&quot;cn.cisol.mvcdemo&quot;&gt;
    &lt;context:include-filter type=&quot;annotation&quot;
        expression=&quot;org.springframework.stereotype.Controller&quot; /&gt;
&lt;/context:component-scan&gt;


&lt;mvc:annotation-driven /&gt;


&lt;mvc:resources mapping=&quot;/resources/**&quot; location=&quot;/resources/&quot; /&gt;



&lt;bean
    class=&quot;org.springframework.web.servlet.view.ContentNegotiatingViewResolver&quot;&gt;
    &lt;property name=&quot;order&quot; value=&quot;1&quot; /&gt;
    &lt;property name=&quot;mediaTypes&quot;&gt;
        &lt;map&gt;
            &lt;entry key=&quot;json&quot; value=&quot;application/json&quot; /&gt;
            &lt;entry key=&quot;xml&quot; value=&quot;application/xml&quot; /&gt;
            &lt;entry key=&quot;htm&quot; value=&quot;text/html&quot; /&gt;
        &lt;/map&gt;
    &lt;/property&gt;

    &lt;property name=&quot;defaultViews&quot;&gt;
        &lt;list&gt;

            &lt;bean
                class=&quot;org.springframework.web.servlet.view.json.MappingJackson2JsonView&quot;&gt;
            &lt;/bean&gt;
        &lt;/list&gt;
    &lt;/property&gt;
    &lt;property name=&quot;ignoreAcceptHeader&quot; value=&quot;true&quot; /&gt;
&lt;/bean&gt;

&lt;bean
    class=&quot;org.springframework.web.servlet.view.InternalResourceViewResolver&quot;&gt;
    &lt;property name=&quot;viewClass&quot;
        value=&quot;org.springframework.web.servlet.view.JstlView&quot; /&gt;
    &lt;property name=&quot;prefix&quot; value=&quot;/WEB-INF/jsps/&quot; /&gt;
    &lt;property name=&quot;suffix&quot; value=&quot;.jsp&quot; /&gt;
&lt;/bean&gt;



&lt;bean id=&quot;multipartResolver&quot;
    class=&quot;org.springframework.web.multipart.commons.CommonsMultipartResolver&quot;&gt;
    &lt;property name=&quot;maxUploadSize&quot; value=&quot;209715200&quot; /&gt;
    &lt;property name=&quot;defaultEncoding&quot; value=&quot;UTF-8&quot; /&gt;
    &lt;property name=&quot;resolveLazily&quot; value=&quot;true&quot; /&gt;
&lt;/bean&gt;
</code></pre><p>&lt;/beans&gt;</p>
<pre><code>            -                 xmlns=&quot;http://www.itcast.cn/xml&quot;
            -                 xsi:schemaLocation=&quot;http://www.itcast.cn/xml  student.xsd&quot;&gt;
</code></pre><h3 id="03-xml-解析"><a href="#03-xml-解析" class="headerlink" title="03 xml_解析"></a>03 xml_解析</h3><ul>
<li>解析：操作xml文档，将文档中的数据读取到内存中</li>
<li><ul>
<li><p>操作xml文档</p>
<ul>
<li><ol>
<li>解析(读取)：将文档中的数据读取到内存中</li>
</ol>
</li>
<li><ol>
<li>写入：将内存中的数据保存到xml文档中。持久化的存储</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>解析xml的方式：</p>
<ul>
<li><ol>
<li><p>DOM：将标记语言文档一次性加载进内存，在内存中形成一颗dom树</p>
<ul>
<li><ul>
<li>优点：操作方便，可以对文档进行CRUD的所有操作</li>
</ul>
</li>
<li><ul>
<li>缺点：占内存</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>SAX：逐行读取，基于事件驱动的。</p>
<ul>
<li><ul>
<li>优点：不占内存。</li>
</ul>
</li>
<li><ul>
<li>缺点：只能读取，不能增删改</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>xml常见的解析器：</p>
<ul>
<li>JAXP：sun公司提供的解析器，支持dom和sax两种思想。</li>
<li>DOM4J：一款非常优秀的解析器。</li>
<li>Jsoup：jsoup 是一款Java 的HTML解析器，可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API，可通过DOM，CSS以及类似于jQuery的操作方法来取出和操作数据。</li>
<li>PULL：Android操作系统内置的解析器，sax方式的。</li>
<li><ul>
<li><p>Jsoup：jsoup 是一款Java 的HTML解析器，可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API，可通过DOM，CSS以及类似于jQuery的操作方法来取出和操作数据。</p>
<ul>
<li><ul>
<li><p>步骤：</p>
<ul>
<li>导入jar包</li>
<li>获取Document对象</li>
<li>获取对应的标签Element对象</li>
<li>获取数据</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>代码：…</p>
<ul>
<li>/**</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>Jsoup快速入门<br>*/<br>public class JsoupDemo1 {<br>public static void main(String[] args) throws IOException {</p>
<pre><code>//2.获取Document对象，根据xml文档获取
//2.1获取student.xml的path
String path = JsoupDemo1.class.getClassLoader().getResource(&quot;student.xml&quot;).getPath();
//2.2解析xml文档，加载文档进内存，获取dom树---&gt;Document
Document document = Jsoup.parse(new File(path), &quot;utf-8&quot;);
//3.获取元素对象 Element
Elements elements = document.getElementsByTag(&quot;name&quot;);
System.out.println(elements.size());
//3.1获取第一个name的Element对象
Element element = elements.get(0);
//3.2获取数据
String name = element.text();
System.out.println(name);
</code></pre><p>}<br>}</p>
<pre><code>- * 对象的使用：

    - 1. Jsoup：工具类，可以解析html或xml文档，返回Document。

        - * parse：解析html或xml文档，返回Document
        - * parse​(File in, String charsetName)：解析xml或html文件的。
        - * parse​(String html)：解析xml或html字符串
        - * parse​(URL url, int timeoutMillis)：通过网络路径获取指定的html或xml的文档对象

    - 2. Document：文档对象，代表内存中的dom树。
    - 3. Elements：元素Element对象的集合，可以当做 ArrayList&lt;Element&gt;来使用。
    - 4. Element：元素对象
    - 5. Node：节点对象

- * 快捷查询方式：

    - 1. selector：选择器

        - * 使用的方法：Elements    select​(String cssQuery)
        - * 语法：参考Selector类中定义的语法

    - 2. XPath：XPath即为XML路径语言，它是一种用来确定XML（标准通用标记语言的子集）文档中某部分位置的语言。

        - * 使用Jsoup的Xpath需要额外导入jar包。
        - * 查询w3cshool参考手册，使用xpath的语法完成查询

    - * 代码：

        - /**
</code></pre></li>
<li><p>XPath查询<br>*/<br>public class JsoupDemo6 {<br>public static void main(String[] args) throws IOException, XpathSyntaxErrorException {</p>
<pre><code>//1.获取student.xml的path
String path = JsoupDemo6.class.getClassLoader().getResource(&quot;student.xml&quot;).getPath();
//2.获取Document对象
Document document = Jsoup.parse(new File(path), &quot;utf-8&quot;);

//3.根据document对象，创建JXDocument对象
JXDocument jxDocument = new JXDocument(document);

//4.结合xpath语法查询
//4.1查询所有student标签
List&lt;JXNode&gt; jxNodes = jxDocument.selN(&quot;//student&quot;);
for (JXNode jxNode : jxNodes) &#123;
    System.out.println(jxNode);
&#125;

System.out.println(&quot;--------------------&quot;);

//4.2查询所有student标签下的name标签
List&lt;JXNode&gt; jxNodes2 = jxDocument.selN(&quot;//student/name&quot;);
for (JXNode jxNode : jxNodes2) &#123;
    System.out.println(jxNode);
&#125;

System.out.println(&quot;--------------------&quot;);

//4.3查询student标签下带有id属性的name标签
List&lt;JXNode&gt; jxNodes3 = jxDocument.selN(&quot;//student/name[@id]&quot;);
for (JXNode jxNode : jxNodes3) &#123;
    System.out.println(jxNode);
&#125;
System.out.println(&quot;--------------------&quot;);
//4.4查询student标签下带有id属性的name标签 并且id属性值为itcast

List&lt;JXNode&gt; jxNodes4 = jxDocument.selN(&quot;//student/name[@id=&#39;itcast&#39;]&quot;);
for (JXNode jxNode : jxNodes4) &#123;
    System.out.println(jxNode);
&#125;
</code></pre><p>}</p>
</li>
</ul>
</li>
</ul>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://goofyer.gitee.io/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E4%B9%9D%E7%AB%A0XML/" data-id="cl403sxrc001tf8vu8etvf10t" data-title="" class="article-share-link">Share</a>
      
      
      
    </footer>
  </div>
  
</article>



  
    <article id="post-Java/第十八章BootStrap" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E5%85%AB%E7%AB%A0BootStrap/" class="article-date">
  <time class="dt-published" datetime="2021-12-19T17:35:17.470Z" itemprop="datePublished">2021-12-20</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h2 id="第十八章BootStrap"><a href="#第十八章BootStrap" class="headerlink" title="第十八章BootStrap"></a>第十八章BootStrap</h2><h3 id="1-概念：-一个前端开发的框架，Bootstrap，来自-Twitter，是目前很受欢迎的前端框架。Bootstrap-是基于-HTML、CSS、JavaScript-的，它简洁灵活，使得-Web-开发更加快捷。"><a href="#1-概念：-一个前端开发的框架，Bootstrap，来自-Twitter，是目前很受欢迎的前端框架。Bootstrap-是基于-HTML、CSS、JavaScript-的，它简洁灵活，使得-Web-开发更加快捷。" class="headerlink" title="1. 概念： 一个前端开发的框架，Bootstrap，来自 Twitter，是目前很受欢迎的前端框架。Bootstrap 是基于 HTML、CSS、JavaScript 的，它简洁灵活，使得 Web 开发更加快捷。"></a>1. 概念： 一个前端开发的框架，Bootstrap，来自 Twitter，是目前很受欢迎的前端框架。Bootstrap 是基于 HTML、CSS、JavaScript 的，它简洁灵活，使得 Web 开发更加快捷。</h3><ul>
<li><ul>
<li>框架：一个半成品软件，开发人员可以在框架基础上，再进行开发，简化编码。</li>
</ul>
</li>
<li><ul>
<li><p>好处：</p>
<ul>
<li><ol>
<li>定义了很多的css样式和js插件。我们开发人员直接可以使用这些样式和插件得到丰富的页面效果。</li>
</ol>
</li>
<li><ol>
<li><p>响应式布局</p>
<ul>
<li><ul>
<li>同一套页面可以兼容不同分辨率的设备。</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><p>把基础性的知识封装（让开发更简单）—&gt; 提供jar包 —&gt; 开发人员可以借助jar包快速地开发程序。—&gt; 框架，一个半成品软件。</p>
</li>
<li><p>Bootstrap 模板</p>
<ul>
<li><p>&lt;!DOCTYPE html&gt;</p>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面，任何其他内容都*必须*跟随其后！ -->
<title>Bootstrap 101 Template</title>

<!-- Bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">

<!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询（media queries）功能 -->
<!-- 警告：通过 file:// 协议（就是直接将 html 页面拖拽到浏览器中）访问页面时 Respond.js 不起作用 -->
<!--[if lt IE 9]>
<script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
<![endif]-->
</head>
<body>
<h1>你好，世界！</h1>

<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery，所以必须放在前边) -->
<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
</body>
</html>

</li>
</ul>
</li>
</ul>
<h3 id="02-Bootstrap-栅格系统"><a href="#02-Bootstrap-栅格系统" class="headerlink" title="02 Bootstrap_栅格系统"></a>02 Bootstrap_栅格系统</h3><ul>
<li><p>响应式布局</p>
<ul>
<li><ul>
<li>同一套页面可以兼容不同分辨率的设备。</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li>实现：依赖于栅格系统：将一行平均分成12个格子，可以指定元素占几个格子。</li>
</ul>
</li>
<li><ul>
<li><p>步骤：</p>
<ul>
<li><ol>
<li><p>定义容器。相当于之前的table。</p>
<ul>
<li><ul>
<li><p>容器分类：</p>
<ul>
<li><ol>
<li>container：两边留白</li>
</ol>
</li>
<li><ol>
<li>container-fluid：每一种设备都是100%宽度</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li>定义行。相当于之前的tr，样式：row</li>
</ol>
</li>
<li><ol>
<li><p>定义元素。指定该元素在不同的设备上，所占的格子数目。样式：col-设备代号-格子数目</p>
<ul>
<li><ul>
<li><p>设备代号：</p>
<ul>
<li><ol>
<li>xs：超小屏幕 手机 (&lt;768px)：col-xs-12</li>
</ol>
</li>
<li><ol>
<li>sm：小屏幕 平板 (≥768px)</li>
</ol>
</li>
<li><ol>
<li>md：中等屏幕 桌面显示器 (≥992px)</li>
</ol>
</li>
<li><ol>
<li>lg：大屏幕 大桌面显示器 (≥1200px)</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="03-Bootstrap-全局CSS样式"><a href="#03-Bootstrap-全局CSS样式" class="headerlink" title="03 Bootstrap_全局CSS样式"></a>03 Bootstrap_全局CSS样式</h3><ul>
<li><ol>
<li><p>全局CSS样式：</p>
<ul>
<li><ul>
<li>按钮：class=”btn btn-default”</li>
</ul>
</li>
<li><ul>
<li><p>图片：</p>
<ul>
<li><ul>
<li>class=”img-responsive”：图片在任意尺寸都占100%（响应式）</li>
</ul>
</li>
<li><ul>
<li><p>图片形状</p>
<ul>
<li><ul>
<li><img src="..." alt="..." class="img-rounded"> ：方形</li>
</ul>
</li>
<li><ul>
<li><img src="..." alt="..." class="img-circle">  ：圆形</li>
</ul>
</li>
<li><ul>
<li><img src="..." alt="..." class="img-thumbnail"> ：相框</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>表格</p>
<ul>
<li><ul>
<li>table</li>
</ul>
</li>
<li><ul>
<li>table-bordered：表格边框</li>
</ul>
</li>
<li><ul>
<li>table-hover：表格悬浮变色</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>表单</p>
<ul>
<li><ul>
<li>给表单项添加：class=”form-control” </li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>组件：</p>
<ul>
<li><ul>
<li>导航条</li>
</ul>
</li>
<li><ul>
<li>分页条</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>插件：</p>
<ul>
<li><ul>
<li>轮播图</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
<h3 id="04-Bootstrap-组件和插件"><a href="#04-Bootstrap-组件和插件" class="headerlink" title="04 Bootstrap_组件和插件"></a>04 Bootstrap_组件和插件</h3><ul>
<li>导航条</li>
<li><p>&lt;!DOCTYPE html&gt;<br><html lang="zh-CN"><br>  <head></p>
<pre><code>  &lt;meta charset=&quot;utf-8&quot;&gt;
  &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;
  &lt;!-- 上述3个meta标签*必须*放在最前面，任何其他内容都*必须*跟随其后！ --&gt;
  &lt;title&gt;Bootstrap HelloWorld&lt;/title&gt;

  &lt;!-- Bootstrap --&gt;
  &lt;link href=&quot;css/bootstrap.min.css&quot; rel=&quot;stylesheet&quot;&gt;

  &lt;!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery，所以必须放在前边) --&gt;
  &lt;script src=&quot;js/jquery-3.2.1.min.js&quot;&gt;&lt;/script&gt;
  &lt;!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 --&gt;
  &lt;script src=&quot;js/bootstrap.min.js&quot;&gt;&lt;/script&gt;
</code></pre><p>  &lt;/head&gt;</p>
  <body>
      <nav class="navbar navbar-inverse">
          <div class="container-fluid">
              <!-- Brand and toggle get grouped for better mobile display -->
              <div class="navbar-header">
                  <!-- 定义汉堡按钮 -->
                  <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"
                   aria-expanded="false">
                      <span class="sr-only">Toggle navigation</span>
                      <span class="icon-bar"></span>
                      <span class="icon-bar"></span>
                      <span class="icon-bar"></span>
                  </button>
                  <a class="navbar-brand" href="#">首页</a>
              </div>

              <!-- Collect the nav links, forms, and other content for toggling -->
              <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                  <ul class="nav navbar-nav">
                      <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
                      <li><a href="#">Link</a></li>
                      <li class="dropdown">
                          <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown
                              <span class="caret"></span></a>
                          <ul class="dropdown-menu">
                              <li><a href="#">Action</a></li>
                              <li><a href="#">Another action</a></li>
                              <li><a href="#">Something else here</a></li>
                              <li role="separator" class="divider"></li>
                              <li><a href="#">Separated link</a></li>
                              <li role="separator" class="divider"></li>
                              <li><a href="#">One more separated link</a></li>
                          </ul>
                      </li>
                  </ul>
                  <ul class="nav navbar-nav navbar-right">
                      <li><a href="#">Link</a></li>
                      <li class="dropdown">
                          <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown
                              <span class="caret"></span></a>
                          <ul class="dropdown-menu">
                              <li><a href="#">Action</a></li>
                              <li><a href="#">Another action</a></li>
                              <li><a href="#">Something else here</a></li>
                              <li role="separator" class="divider"></li>
                              <li><a href="#">Separated link</a></li>
                          </ul>
                      </li>
                  </ul>
              </div><!-- /.navbar-collapse -->
          </div><!-- /.container-fluid -->
      </nav>
  </body>

</li>
</ul>
<p>分页条</p>
<p>&lt;!DOCTYPE html&gt;</p>
<p><html lang="zh-CN"><br>    <head><br>        <meta charset="utf-8"><br>        <meta http-equiv="X-UA-Compatible" content="IE=edge"><br>        <meta name="viewport" content="width=device-width, initial-scale=1"><br>        <!-- 上述3个meta标签*必须*放在最前面，任何其他内容都*必须*跟随其后！ --><br>        <title>Bootstrap HelloWorld</title></p>
<pre><code>    &lt;!-- Bootstrap --&gt;
    &lt;link href=&quot;css/bootstrap.min.css&quot; rel=&quot;stylesheet&quot;&gt;

    &lt;!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery，所以必须放在前边) --&gt;
    &lt;script src=&quot;js/jquery-3.2.1.min.js&quot;&gt;&lt;/script&gt;
    &lt;!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 --&gt;
    &lt;script src=&quot;js/bootstrap.min.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;nav aria-label=&quot;Page navigation&quot;&gt;
        &lt;ul class=&quot;pagination&quot;&gt;
            &lt;li class=&quot;disabled&quot;&gt;
                &lt;a href=&quot;#&quot; aria-label=&quot;Previous&quot;&gt;
                    &lt;span aria-hidden=&quot;true&quot;&gt;&amp;laquo;&lt;/span&gt;
                &lt;/a&gt;
            &lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;#&quot;&gt;1&lt;/a&gt;&lt;/li&gt;
            &lt;li class=&quot;active&quot;&gt;&lt;a href=&quot;#&quot;&gt;2&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;#&quot;&gt;3&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;#&quot;&gt;4&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;#&quot;&gt;5&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;
                &lt;a href=&quot;#&quot; aria-label=&quot;Next&quot;&gt;
                    &lt;span aria-hidden=&quot;true&quot;&gt;&amp;raquo;&lt;/span&gt;
                &lt;/a&gt;
            &lt;/li&gt;
        &lt;/ul&gt;
    &lt;/nav&gt;
&lt;/body&gt;
</code></pre><p>Bootstrap_插件_轮播图</p>
<p>&lt;!DOCTYPE html&gt;</p>
<p><html lang="zh-CN"><br>    <head><br>        <meta charset="utf-8"><br>        <meta http-equiv="X-UA-Compatible" content="IE=edge"><br>        <meta name="viewport" content="width=device-width, initial-scale=1"><br>        <!-- 上述3个meta标签*必须*放在最前面，任何其他内容都*必须*跟随其后！ --><br>        <title>Bootstrap HelloWorld</title></p>
<pre><code>    &lt;!-- Bootstrap --&gt;
    &lt;link href=&quot;css/bootstrap.min.css&quot; rel=&quot;stylesheet&quot;&gt;

    &lt;!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery，所以必须放在前边) --&gt;
    &lt;script src=&quot;js/jquery-3.2.1.min.js&quot;&gt;&lt;/script&gt;
    &lt;!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 --&gt;
    &lt;script src=&quot;js/bootstrap.min.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div id=&quot;carousel-example-generic&quot; class=&quot;carousel slide&quot; data-ride=&quot;carousel&quot;&gt;
        &lt;!-- Indicators --&gt;
        &lt;ol class=&quot;carousel-indicators&quot;&gt;
            &lt;li data-target=&quot;#carousel-example-generic&quot; data-slide-to=&quot;0&quot; class=&quot;active&quot;&gt;&lt;/li&gt;
            &lt;li data-target=&quot;#carousel-example-generic&quot; data-slide-to=&quot;1&quot;&gt;&lt;/li&gt;
            &lt;li data-target=&quot;#carousel-example-generic&quot; data-slide-to=&quot;2&quot;&gt;&lt;/li&gt;
        &lt;/ol&gt;

        &lt;!-- Wrapper for slides --&gt;
        &lt;div class=&quot;carousel-inner&quot; role=&quot;listbox&quot;&gt;
            &lt;div class=&quot;item active&quot;&gt;
                &lt;img src=&quot;img/banner_1.jpg&quot; alt=&quot;...&quot;&gt;
            &lt;/div&gt;
            &lt;div class=&quot;item&quot;&gt;
                &lt;img src=&quot;img/banner_2.jpg&quot; alt=&quot;...&quot;&gt;
            &lt;/div&gt;
            &lt;div class=&quot;item&quot;&gt;
                &lt;img src=&quot;img/banner_3.jpg&quot; alt=&quot;...&quot;&gt;
            &lt;/div&gt;
        &lt;/div&gt;

        &lt;!-- Controls --&gt;
        &lt;a class=&quot;left carousel-control&quot; href=&quot;#carousel-example-generic&quot; role=&quot;button&quot; data-slide=&quot;prev&quot;&gt;
            &lt;span class=&quot;glyphicon glyphicon-chevron-left&quot; aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;
            &lt;span class=&quot;sr-only&quot;&gt;Previous&lt;/span&gt;
        &lt;/a&gt;
        &lt;a class=&quot;right carousel-control&quot; href=&quot;#carousel-example-generic&quot; role=&quot;button&quot; data-slide=&quot;next&quot;&gt;
            &lt;span class=&quot;glyphicon glyphicon-chevron-right&quot; aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;
            &lt;span class=&quot;sr-only&quot;&gt;Next&lt;/span&gt;
        &lt;/a&gt;
    &lt;/div&gt;
&lt;/body&gt;
</code></pre><h3 id="5-案例-黑马旅游网"><a href="#5-案例-黑马旅游网" class="headerlink" title="5 案例_黑马旅游网"></a>5 案例_黑马旅游网</h3><ul>
<li>子主题 1</li>
<li>子主题 2</li>
<li>子主题 3</li>
<li>子主题 4</li>
<li>子主题 5</li>
<li>子主题 6</li>
<li>子主题 15</li>
<li>子主题 16</li>
<li>子主题 17</li>
<li>子主题 18</li>
<li>子主题 19</li>
<li>子主题 20</li>
<li>子主题 7</li>
<li>子主题 8</li>
<li>&lt;!DOCTYPE html&gt;<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <!-- 上述3个meta标签*必须*放在最前面，任何其他内容都*必须*跟随其后！ -->
  <title>Bootstrap HelloWorld</title>
  <!-- Bootstrap -->
  <link href="css/bootstrap.min.css" rel="stylesheet">
  <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery，所以必须放在前边) -->
  <script src="js/jquery-3.2.1.min.js"></script>
  <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
  <script src="js/bootstrap.min.js"></script>
  <style>
      .paddtop {
          padding-top: 10px;
      }
      .search-btn {
          float: left;
          border: 1px solid #ffc900;
          width: 90px;
          height: 35px;
          background-color: #ffc900;
          text-align: center;
          line-height: 35px;
          margin-top: 15px;
      }
      .search-input {
          float: left;
          border: 2px solid #ffc900;
          width: 400px;
          height: 35px;
          padding-left: 5px;
          margin-top: 15px;
      }
      .jx {
          border-bottom: 2px solid #ffc900;
          padding: 5px;
      }
      .company {
          height: 40px;
          background-color: #ffc900;
          text-align: center;
          line-height: 40px;
          font-size: 8px;
      }
  </style>
</head>
<body>
  <!-- 1.页眉部分-->
  <header class="container-fluid">
      <div class="row">
          <img src="img/top_banner.jpg" class="img-responsive">
      </div>
      <div class="row paddtop">
          <div class="col-md-3">
              <img src="img/logo.jpg" class="img-responsive">
          </div>
          <div class="col-md-5">
              <input class="search-input" placeholder="请输入线路名称">
              <a class="search-btn" href="#">搜索</a>
          </div>
          <div class="col-md-4">
              <img src="img/hotel_tel.png" class="img-responsive">
          </div>
      </div>
      <!--导航栏-->
      <div class="row">
          <nav class="navbar navbar-default">
              <div class="container-fluid">
                  <!-- Brand and toggle get grouped for better mobile display -->
                  <div class="navbar-header">
                      <!-- 定义汉堡按钮 -->
                      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                          data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                          <span class="sr-only">Toggle navigation</span>
                          <span class="icon-bar"></span>
                          <span class="icon-bar"></span>
                          <span class="icon-bar"></span>
                      </button>
                      <a class="navbar-brand" href="#">首页</a>
                  </div>
                  <!-- Collect the nav links, forms, and other content for toggling -->
                  <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                      <ul class="nav navbar-nav">
                          <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
                          <li><a href="#">Link</a></li>
                          <li><a href="#">Link</a></li>
                          <li><a href="#">Link</a></li>
                          <li><a href="#">Link</a></li>
                          <li><a href="#">Link</a></li>
                      </ul>
                  </div><!-- /.navbar-collapse -->
              </div><!-- /.container-fluid -->
          </nav>
      </div>
      <!--轮播图-->
      <div class="row">
          <div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
              <!-- Indicators -->
              <ol class="carousel-indicators">
                  <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
                  <li data-target="#carousel-example-generic" data-slide-to="1"></li>
                  <li data-target="#carousel-example-generic" data-slide-to="2"></li>
              </ol>
              <!-- Wrapper for slides -->
              <div class="carousel-inner" role="listbox">
                  <div class="item active">
                      <img src="img/banner_1.jpg" alt="...">
                  </div>
                  <div class="item">
                      <img src="img/banner_2.jpg" alt="...">
                  </div>
                  <div class="item">
                      <img src="img/banner_3.jpg" alt="...">
                  </div>
              </div>
              <!-- Controls -->
              <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
                  <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
                  <span class="sr-only">Previous</span>
              </a>
              <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
                  <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
                  <span class="sr-only">Next</span>
              </a>
          </div>
      </div>
  </header>
  <!-- 2.主体部分-->
  <div class="container">
      <div class="row jx">
          <img src="img/icon_5.jpg">
          <span>黑马精选</span>
      </div>
      <div class="row paddtop">
          <div class="col-md-3">
              <div class="thumbnail">
                  <img src="img/jiangxuan_3.jpg" alt="">
                  <p>上海直飞三亚5天4晚自由行(春节预售+亲子/蜜月/休闲游首选+豪华酒店任选+接送机)</p>
                  <font color="red">&yen; 699</font>
              </div>
          </div>
          <div class="col-md-3">
              <div class="thumbnail">
                  <img src="img/jiangxuan_3.jpg" alt="">
                  <p>上海直飞三亚5天4晚自由行(春节预售+亲子/蜜月/休闲游首选+豪华酒店任选+接送机)</p>
                  <font color="red">&yen; 699</font>
              </div>
          </div>
          <div class="col-md-3">
              <div class="thumbnail">
                  <img src="img/jiangxuan_3.jpg" alt="">
                  <p>上海直飞三亚5天4晚自由行(春节预售+亲子/蜜月/休闲游首选+豪华酒店任选+接送机)</p>
                  <font color="red">&yen; 699</font>
              </div>
          </div>
          <div class="col-md-3">
              <div class="thumbnail">
                  <img src="img/jiangxuan_3.jpg" alt="">
                  <p>上海直飞三亚5天4晚自由行(春节预售+亲子/蜜月/休闲游首选+豪华酒店任选+接送机)</p>
                  <font color="red">&yen; 699</font>
              </div>
          </div>
      </div>
      <div class="row jx">
          <img src="img/icon_6.jpg">
          <span>国内游</span>
      </div>
      <div class="row paddtop">
          <div class="col-md-4">
              <img src="img/guonei_1.jpg">
          </div>
          <div class="col-md-8">
              <div class="row">
                  <div class="col-md-4">
                      <div class="thumbnail">
                          <img src="img/jiangxuan_3.jpg" alt="">
                          <p>上海直飞三亚5天4晚自由行(春节预售+亲子/蜜月/休闲游首选+豪华酒店任选+接送机)</p>
                          <font color="red">&yen; 699</font>
                      </div>
                  </div>
                  <div class="col-md-4">
                      <div class="thumbnail">
                          <img src="img/jiangxuan_3.jpg" alt="">
                          <p>上海直飞三亚5天4晚自由行(春节预售+亲子/蜜月/休闲游首选+豪华酒店任选+接送机)</p>
                          <font color="red">&yen; 699</font>
                      </div>
                  </div>
                  <div class="col-md-4">
                      <div class="thumbnail">
                          <img src="img/jiangxuan_3.jpg" alt="">
                          <p>上海直飞三亚5天4晚自由行(春节预售+亲子/蜜月/休闲游首选+豪华酒店任选+接送机)</p>
                          <font color="red">&yen; 699</font>
                      </div>
                  </div>
              </div>
              <div class="row">
                  <div class="col-md-4">
                      <div class="thumbnail">
                          <img src="img/jiangxuan_3.jpg" alt="">
                          <p>上海直飞三亚5天4晚自由行(春节预售+亲子/蜜月/休闲游首选+豪华酒店任选+接送机)</p>
                          <font color="red">&yen; 699</font>
                      </div>
                  </div>
                  <div class="col-md-4">
                      <div class="thumbnail">
                          <img src="img/jiangxuan_3.jpg" alt="">
                          <p>上海直飞三亚5天4晚自由行(春节预售+亲子/蜜月/休闲游首选+豪华酒店任选+接送机)</p>
                          <font color="red">&yen; 699</font>
                      </div>
                  </div>
                  <div class="col-md-4">
                      <div class="thumbnail">
                          <img src="img/jiangxuan_3.jpg" alt="">
                          <p>上海直飞三亚5天4晚自由行(春节预售+亲子/蜜月/休闲游首选+豪华酒店任选+接送机)</p>
                          <font color="red">&yen; 699</font>
                      </div>
                  </div>
              </div>
          </div>
      </div>
  </div>
  <!-- 3.页脚部分-->
  <footer class="container-fluid">
      <div class="row">
          <img src="img/footer_service.png" class="img-responsive">
      </div>
      <div class="row company">
          江苏传智播客教育科技股份有限公司 版权所有Copyright 2006-2018, All Rights Reserved 苏ICP备16007882
      </div>
  </footer>
</body>
</html></li>
<li>子主题 10</li>
<li>子主题 14</li>
<li>子主题 11</li>
<li>子主题 12</li>
<li>子主题 13</li>
</ul>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://goofyer.gitee.io/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E5%85%AB%E7%AB%A0BootStrap/" data-id="cl403sxrd001wf8vu180y4gqz" data-title="" class="article-share-link">Share</a>
      
      
      
    </footer>
  </div>
  
</article>



  
    <article id="post-Java/第十七章JavaScript" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E4%B8%83%E7%AB%A0JavaScript/" class="article-date">
  <time class="dt-published" datetime="2021-12-19T17:34:51.276Z" itemprop="datePublished">2021-12-20</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h2 id="第十七章JavaScript"><a href="#第十七章JavaScript" class="headerlink" title="第十七章JavaScript"></a>第十七章JavaScript</h2>
      
    </div>
    <footer class="article-footer">
      <a data-url="https://goofyer.gitee.io/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E4%B8%83%E7%AB%A0JavaScript/" data-id="cl403sxrb001qf8vu33u96jih" data-title="" class="article-share-link">Share</a>
      
      
      
    </footer>
  </div>
  
</article>



  
    <article id="post-Java/第十六章HTML和CSS" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E5%85%AD%E7%AB%A0HTML%E5%92%8CCSS/" class="article-date">
  <time class="dt-published" datetime="2021-12-19T17:34:41.500Z" itemprop="datePublished">2021-12-20</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h2 id="第十六章HTML和CSS"><a href="#第十六章HTML和CSS" class="headerlink" title="第十六章HTML和CSS"></a>第十六章HTML和CSS</h2><h3 id="HTML概念介绍"><a href="#HTML概念介绍" class="headerlink" title="HTML概念介绍"></a>HTML概念介绍</h3><ul>
<li><ol>
<li><p>概念：是最基础的网页开发语言</p>
<ul>
<li><ul>
<li><p>Hyper Text Markup Language 超文本标记语言</p>
<ul>
<li><ul>
<li><p>超文本:</p>
<ul>
<li><ul>
<li>超文本是用超链接的方法，将各种不同空间的文字信息组织在一起的网状文本.</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>标记语言:</p>
<ul>
<li><ul>
<li>由标签构成的语言。&lt;标签名称&gt; 如 html，xml</li>
</ul>
</li>
<li><ul>
<li>标记语言不是编程语言。</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>快速入门：</p>
<ul>
<li><ul>
<li><p>语法：</p>
<ul>
<li><ol>
<li>html文档后缀名 .html 或者 .htm</li>
</ol>
</li>
<li><ol>
<li><p>标签分为</p>
<ul>
<li><ol>
<li>围堵标签：有开始标签和结束标签。如 <html> </html></li>
</ol>
</li>
<li><ol>
<li>自闭和标签：开始标签和结束标签在一起。如 <br/></li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>标签可以嵌套：</p>
<ul>
<li>需要正确嵌套，不能你中有我，我中有你</li>
<li>错误：<a><b></a>&lt;/b&gt;</li>
<li>正确：<a><b></b></a></li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li>在开始标签中可以定义属性。属性是由键值对构成，值需要用引号(单双都可)引起来。</li>
</ol>
</li>
<li><ol>
<li>html的标签不区分大小写，但是建议使用小写。</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>代码：</p>
<ul>
<li><html>

<head>
<title>title</title>
</head>

<body>
<FONT color='red'>Hello World</font><br/>

<font color='green'>Hello World</font>

</body>

</li>
</ul>
<p>&lt;/html&gt;</p>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
<h3 id="第2节-基本标签"><a href="#第2节-基本标签" class="headerlink" title="第2节 基本标签"></a>第2节 基本标签</h3><ul>
<li><ol>
<li><p>文件标签：构成html最基本的标签</p>
<ul>
<li><ul>
<li>html：html文档的根标签。</li>
</ul>
</li>
<li><ul>
<li>head：头标签，用于指定html文档的一些属性；引入外部的资源。</li>
</ul>
</li>
<li><ul>
<li>title：标题标签。</li>
</ul>
</li>
<li><ul>
<li>body：体标签。</li>
</ul>
</li>
<li><ul>
<li>&lt;!DOCTYPE html&gt;：html5中定义该文档是html文档。</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>文本标签：和文本有关的标签</p>
<ul>
<li><ul>
<li><p>属性：</p>
<ul>
<li><ul>
<li>注释：<!-- 注释内容 --></li>
</ul>
</li>
<li><ul>
<li><h1> to <h6>：标题标签,h1~h6:字体大小逐渐递减</li>
</ul>
</li>
<li><ul>
<li><p>：段落标签</li>
</ul>
</li>
<li><ul>
<li><br>：换行标签</li>
</ul>
</li>
<li><ul>
<li><hr>：展示一条水平线</li>
</ul>
</li>
<li><ul>
<li>color：颜色</li>
</ul>
</li>
<li><ul>
<li>width：宽度</li>
</ul>
</li>
<li><ul>
<li>size：高度</li>
</ul>
</li>
<li><ul>
<li><p>align：对齐方式</p>
<ul>
<li><ul>
<li>center：居中</li>
</ul>
</li>
<li><ul>
<li>left：左对齐</li>
</ul>
</li>
<li><ul>
<li>right：右对齐</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><b>：字体加粗</li>
</ul>
</li>
<li><ul>
<li><i>：字体斜体</li>
</ul>
</li>
<li><ul>
<li><font>：字体标签</li>
</ul>
</li>
<li><ul>
<li><center>：文本居中</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>属性：</p>
<ul>
<li><ul>
<li>color：颜色</li>
</ul>
</li>
<li><ul>
<li>size：大小</li>
</ul>
</li>
<li><ul>
<li>face：字体</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>属性定义：</p>
<ul>
<li><ul>
<li><p>color：</p>
<ul>
<li><ol>
<li>英文单词：red、green、blue</li>
</ol>
</li>
<li><ol>
<li>rgb(值1，值2，值3)：值的范围：0~255，如：rgb(0,0,255)</li>
</ol>
</li>
<li><ol>
<li><h1 id="值1值2值3：值的范围：00-FF之间，如：-FF00FF"><a href="#值1值2值3：值的范围：00-FF之间，如：-FF00FF" class="headerlink" title="值1值2值3：值的范围：00~FF之间，如： #FF00FF"></a>值1值2值3：值的范围：00~FF之间，如： #FF00FF</h1></li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>width：</p>
<ul>
<li><ol>
<li>数值：width=’20’ ,数值的单位，默认是 px(像素)</li>
</ol>
</li>
<li><ol>
<li>数值%：占比相对于父元素的比例</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ul>
<li><p>案例：公司简介</p>
<ul>
<li><p>&lt;!DOCTYPE html&gt;<br><html lang="ch"><br><head>
  <meta charset="UTF-8">
  <title>黑马程序员简介</title>
</head><br><body><br>  <header></p>
<pre><code>  &lt;div id=&quot;header&quot;&gt;
      &lt;h1&gt;
          公司简介
      &lt;/h1&gt;

  &lt;/div&gt;
</code></pre><p>  &lt;/header&gt;</p>
  <hr color="#ffd700">

  <p>
      <font color="#FF0000">"中关村黑马程序员训练营"</font>是由<b><i>传智播客</i></b>联合中关村软件园、CSDN，
      并委托传智播客进行教学实施的软件开发高端培训机构，致力于服务各大软件企业，解决当前软件开发技术飞速发展， 而企业招不到优秀人才的困扰。
  </p>

  <p>
      目前，“中关村黑马程序员训练营”已成长为行业“学员质量好、课程内容深、企业满意”的移动开发高端训练基地， 并被评为中关村软件园重点扶持人才企业。
  </p>

  <p>

      黑马程序员的学员多为大学毕业后，有理想、有梦想，想从事IT行业，而没有环境和机遇改变自己命运的年轻人。 黑马程序员的学员筛选制度，远比现在90%以上的企业招聘流程更为严格。任何一名学员想成功入学“黑马程序员”，
      必须经历长达2个月的面试流程，这些流程中不仅包括严格的技术测试、自学能力测试，还包括性格测试、压力测试、 品德测试等等测试。毫不夸张地说，黑马程序员训练营所有学员都是精挑细选出来的。百里挑一的残酷筛选制度确
      保学员质量，并降低企业的用人风险。
      中关村黑马程序员训练营不仅着重培养学员的基础理论知识，更注重培养项目实施管理能力，并密切关注技术革新， 不断引入先进的技术，研发更新技术课程，确保学员进入企业后不仅能独立从事开发工作，更能给企业带来新的技术体系和理念。
  </p>

  <p>

      一直以来，黑马程序员以技术视角关注IT产业发展，以深度分享推进产业技术成长，致力于弘扬技术创新，倡导分享、 开放和协作，努力打造高质量的IT人才服务平台。
  </p>

<p>  <hr color="#ffd700"></p>
  <footer>

      <div id="footer">
          <font color="gray" size="2">
              <center>
                  江苏传智播客教育科技股份有限公司<br>
                  版权所有Copyright 2006-2018&copy;, All Rights Reserved 苏ICP备16007882
              </center>
          </font>
      </div>
  </footer>

</li>
</ul>
<p>&lt;/body&gt;<br>&lt;/html&gt;</p>
</li>
</ul>
</li>
<li><p>图片标签</p>
<ul>
<li>相对路径</li>
<li><p>相对路径</p>
<ul>
<li><ul>
<li><p>以.开头的路径</p>
<ul>
<li><ul>
<li>./：代表当前目录  ./image/1.jpg</li>
</ul>
</li>
<li><ul>
<li>../:代表上一级目录</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>列表标签</p>
<ul>
<li><p>有序列表：</p>
<ul>
<li>ol</li>
<li>li</li>
</ul>
</li>
<li><p>无序列表：</p>
<ul>
<li>ul</li>
<li>li</li>
</ul>
</li>
</ul>
</li>
<li><ol>
<li><p>链接标签：</p>
<ul>
<li><ul>
<li>a：定义一个超链接</li>
</ul>
</li>
<li><ul>
<li><p>属性：</p>
<ul>
<li><ul>
<li>href：指定访问资源的URL(统一资源定位符)</li>
</ul>
</li>
<li><ul>
<li><p>target：指定打开资源的方式</p>
<ul>
<li><ul>
<li>_self：默认值，在当前页面打开</li>
</ul>
</li>
<li><ul>
<li>_blank：在空白页面打开</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><p>表格标签：</p>
<ul>
<li><ul>
<li><p>table：定义表格</p>
<ul>
<li><ul>
<li>width：宽度</li>
</ul>
</li>
<li><ul>
<li>border：边框</li>
</ul>
</li>
<li><ul>
<li>cellpadding：定义内容和单元格的距离。</li>
</ul>
</li>
<li><ul>
<li>cellspacing：定义单元格之间的距离。如果指定为0，则单元格的线会合为一条。</li>
</ul>
</li>
<li><ul>
<li>bgcolor：背景色</li>
</ul>
</li>
<li><ul>
<li>align：对齐方式</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>案例</p>
<ul>
<li><p>&lt;!DOCTYPE html&gt;</p>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>表格标签</title>
</head>
<body>
<table border="1" width="50%" cellpadding="0" cellspacing="0" bgcolor="#faebd7" align="center">
  <tr>
      <!-- <td>编号</td>
      <td>姓名</td>
      <td>成绩</td>-->
      <th>编号</th>
      <th>姓名</th>
      <th>成绩</th>
  </tr>
  <tr>
      <td>1</td>
      <td>小龙女</td>
      <td>100</td>
  </tr>
  <tr>
      <td>2</td>
      <td>杨过</td>
      <td>50</td>
  </tr>
</table>
<hr>
<table border="1" width="50%" cellpadding="0" cellspacing="0" bgcolor="#faebd7" align="center">
  <thead>
      <caption>学生信息表</caption>
      <tr>
          <!-- <td>编号</td>
           <td>姓名</td>
           <td>成绩</td>-->
          <th>编号</th>
          <th>姓名</th>
          <th>成绩</th>
      </tr>
  </thead>
  <tbody>
      <tr bgcolor="#7fffd4" align="center">
          <td>1</td>
          <td>小龙女</td>
          <td>100</td>
      </tr>
      <tr>
          <td>2</td>
          <td>杨过</td>
          <td>50</td>
      </tr>
  </tbody>
  <tfoot>
      <tr>
          <td>3</td>
          <td>老顽童</td>
          <td>10</td>
      </tr>
  </tfoot>
</table>
<hr>
<table border="1" width="50%" cellpadding="0" cellspacing="0" bgcolor="#faebd7" align="center">
  <tr>
      <th rowspan="2">编号</th>
      <th>姓名</th>
      <th>成绩</th>
  </tr>

  <tr>
      <td>小龙女</td>
      <td>100</td>
  </tr>
  <tr>
      <td>2</td>
      <td colspan="2">杨过</td>
  </tr>
</table>
<hr>
</body>
</html>
</li>
</ul>
</li>
</ul>
</li>
<li><p>HTML标签_综合案例</p>
<ul>
<li><ol>
<li>确定使用table来完成布局（12行）</li>
</ol>
</li>
<li><ol>
<li>如果某一行只有一个单元格，则使用<tr><td></td></tr></li>
</ol>
</li>
<li><ol>
<li><p>如果某一行有多个单元格，则使用</p>
<ul>
<li><tr>
<td>
<table></table>
</td>
</tr>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>代码实现 …</p>
<ul>
<li><p>&lt;!DOCTYPE html&gt;</p>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>黑马旅游网</title>
</head>
<body>
<!--采用table来完成布局-->
<!--最外层的table，用于整个页面的布局-->
<table width="100%" align="center">
 <!-- 第1行 -->
 <tr>
     <td>
         <img src="image/top_banner.jpg" width="100%" alt="">
     </td>
 </tr>

 <!-- 第2行 -->
 <tr>
     <td>
         <table width="100%" align="center">
             <tr>
                 <td>
                     <img src="image/logo.jpg" alt="">
                 </td>
                 <td>
                     <img src="image/search.png" alt="">
                 </td>
                 <td>
                     <img src="image/hotel_tel.png" alt="">
                 </td>
             </tr>
         </table>
     </td>
 </tr>

 <!-- 第3行 -->
 <tr>
     <td>
         <table width="100%" align="center">
             <tr bgcolor="#ffd700" align="center" height="45">
                 <td>
                     <a href="">首页</a>
                 </td>
                 <td>
                     门票
                 </td>
                 <td>
                     门票
                 </td>
                 <td>
                     门票
                 </td>
                 <td>
                     门票
                 </td>
                 <td>
                     门票
                 </td>
                 <td>
                     门票
                 </td>
                 <td>
                     门票
                 </td>
                 <td>
                     门票
                 </td>
                 <td>
                     门票
                 </td>
             </tr>
         </table>
     </td>
 </tr>

 <!-- 第4行 轮播图 -->
 <tr>
     <td>
         <img src="image/banner_3.jpg" alt="" width="100%">
     </td>
 </tr>

 <!-- 第5行 黑马精选-->
 <tr>
     <td>
         <img src="image/icon_5.jpg" alt="">
         黑马精选
         <hr color="#ffd700">
     </td>
 </tr>

 <!-- 第6行 -->
 <tr>
     <td>
         <table align="center" width="95%">
             <tr>
                 <td>
                     <img src="image/jiangxuan_1.jpg" alt="">
                     <p>上海飞三亚五天4晚自由行(春节销售+亲子+蜜月+自由行)</p>
                     <font color="red">&yen; 899</font>
                 </td>
                 <td>
                     <img src="image/jiangxuan_1.jpg" alt="">
                     <p>上海飞三亚五天4晚自由行(春节销售+亲子+蜜月+自由行)</p>
                     <font color="red">&yen; 899</font>
                 </td>
                 <td>
                     <img src="image/jiangxuan_1.jpg" alt="">
                     <p>上海飞三亚五天4晚自由行(春节销售+亲子+蜜月+自由行)</p>
                     <font color="red">&yen; 899</font>
                 </td>
                 <td>
                     <img src="image/jiangxuan_1.jpg" alt="">
                     <p>上海飞三亚五天4晚自由行(春节销售+亲子+蜜月+自由行)</p>
                     <font color="red">&yen; 899</font>
                 </td>
             </tr>
         </table>
     </td>
 </tr>

 <!-- 第7行 国内游 -->
 <tr>
     <td>
         <img src="image/icon_6.jpg" alt="">
         国内游
         <hr color="#ffd700">
     </td>
 </tr>

 <!-- 第8行 -->
 <tr>
     <td>
         <table align="center" width="95%">
             <tr>
                 <td rowspan="2">
                     <img src="image/guonei_1.jpg" alt="">
                 </td>
                 <td>
                     <img src="image/jiangxuan_2.jpg" alt="" height="100%">
                     <p>上海飞三亚五天4晚自由行(春节销售+亲子+蜜月+自由行)</p>
                     <font color="red">&yen; 699</font>
                 </td>
                 <td>
                     <img src="image/jiangxuan_2.jpg" alt="">
                     <p>上海飞三亚五天4晚自由行(春节销售+亲子+蜜月+自由行)</p>
                     <font color="red">&yen; 699</font>
                 </td>
                 <td>
                     <img src="image/jiangxuan_2.jpg" alt="">
                     <p>上海飞三亚五天4晚自由行(春节销售+亲子+蜜月+自由行)</p>
                     <font color="red">&yen; 699</font>
                 </td>
             </tr>
             <tr>
                 <td>
                     <img src="image/jiangxuan_2.jpg" alt="">
                     <p>上海飞三亚五天4晚自由行(春节销售+亲子+蜜月+自由行)</p>
                     <font color="red">&yen; 699</font>
                 </td>
                 <td>
                     <img src="image/jiangxuan_2.jpg" alt="">
                     <p>上海飞三亚五天4晚自由行(春节销售+亲子+蜜月+自由行)</p>
                     <font color="red">&yen; 699</font>
                 </td>
                 <td>
                     <img src="image/jiangxuan_2.jpg" alt="">
                     <p>上海飞三亚五天4晚自由行(春节销售+亲子+蜜月+自由行)</p>
                     <font color="red">&yen; 699</font>
                 </td>
             </tr>
         </table>
     </td>
 </tr>

 <!-- 第9行 境外游 -->
 <tr>
     <td>
         <img src="image/icon_7.jpg" alt="">
         境外游
         <hr color="#ffd700">
     </td>
 </tr>

 <!-- 第10行 -->
 <tr>
     <td>
         <table align="center" width="95%">
             <tr>
                 <td rowspan="2">
                     <img src="image/jiangwai_1.jpg" alt="">
                 </td>
                 <td>
                     <img src="image/jiangxuan_3.jpg" alt="" height="100%">
                     <p>上海飞三亚五天4晚自由行(春节销售+亲子+蜜月+自由行)</p>
                     <font color="red">&yen; 699</font>
                 </td>
                 <td>
                     <img src="image/jiangxuan_3.jpg" alt="">
                     <p>上海飞三亚五天4晚自由行(春节销售+亲子+蜜月+自由行)</p>
                     <font color="red">&yen; 699</font>
                 </td>
                 <td>
                     <img src="image/jiangxuan_3.jpg" alt="">
                     <p>上海飞三亚五天4晚自由行(春节销售+亲子+蜜月+自由行)</p>
                     <font color="red">&yen; 699</font>
                 </td>
             </tr>
             <tr>
                 <td>
                     <img src="image/jiangxuan_3.jpg" alt="">
                     <p>上海飞三亚五天4晚自由行(春节销售+亲子+蜜月+自由行)</p>
                     <font color="red">&yen; 699</font>
                 </td>
                 <td>
                     <img src="image/jiangxuan_3.jpg" alt="">
                     <p>上海飞三亚五天4晚自由行(春节销售+亲子+蜜月+自由行)</p>
                     <font color="red">&yen; 699</font>
                 </td>
                 <td>
                     <img src="image/jiangxuan_3.jpg" alt="">
                     <p>上海飞三亚五天4晚自由行(春节销售+亲子+蜜月+自由行)</p>
                     <font color="red">&yen; 699</font>
                 </td>
             </tr>
         </table>
     </td>
 </tr>

 <!-- 第11行 -->
 <tr>
     <td>
         <img src="image/footer_service.png" alt="" width="100%">
     </td>
 </tr>

 <!-- 第12行 -->
 <tr>
     <td align="center" bgcolor="#ffd700" height="40">
         <font color="gray" size="2">
             江苏传智播客教育科技股份有限公司
             版权所有Copyright 2006-2018&copy;, All Rights Reserved 苏ICP备16007882
         </font>
     </td>
 </tr>
</table>
</body>
</html>

</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
<h3 id="第3节-表单标签"><a href="#第3节-表单标签" class="headerlink" title="第3节 表单标签"></a>第3节 表单标签</h3><ul>
<li><ul>
<li><p>表单：</p>
<ul>
<li><ul>
<li>概念：用于采集用户输入的数据的（用于和服务器进行交互）。</li>
</ul>
</li>
<li><ul>
<li><p>form：用于定义表单的。可以定义一个范围，范围代表采集用户数据的范围。</p>
<ul>
<li><ul>
<li><p>属性：</p>
<ul>
<li><ul>
<li>action：指定提交数据的URL</li>
</ul>
</li>
<li><ul>
<li><p>method：指定提交方式</p>
<ul>
<li><ul>
<li><p>分类：一共7种，2种比较常用</p>
<ul>
<li><ul>
<li><p>get：</p>
<ul>
<li><ol>
<li>请求参数会在地址栏中显示。会封装到请求行中(HTTP协议后讲解)。</li>
</ol>
</li>
<li><ol>
<li>请求参数大小是有限制的。</li>
</ol>
</li>
<li><ol>
<li>不太安全。</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>post：</p>
<ul>
<li>1.请求参数不会再地址栏中显示。会封装在请求体中(HTTP协议后讲解)。</li>
<li><ol>
<li>请求参数的大小没有限制。</li>
</ol>
</li>
<li><ol>
<li>较为安全。</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li>表单项中的数据要想被提交：必须指定其name属性。</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>&lt;!DOCTYPE html&gt;</p>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>表单标签</title>
</head>
<body>
  <form action="#" method="post">
      用户名：<input type="text" name="username"><br>
      密码：<input name="password"><br>
      <input type="submit" value="登录">
  </form>
</body>
</html>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>表单项标签：</p>
<ul>
<li><ul>
<li><p>input：可以通过type属性值，改变元素展示的样式</p>
<ul>
<li><ul>
<li><p>type属性：</p>
<ul>
<li><ul>
<li><p>text：文本输入框，默认值</p>
<ul>
<li><ul>
<li>placeholder：指定输入框的提示信息，当输入框的内容发生变化，会自动清空提示信息    </li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li>password：密码输入框</li>
</ul>
</li>
<li><ul>
<li><p>radio:单选框</p>
<ul>
<li><ul>
<li><p>注意：</p>
<ul>
<li><ol>
<li>要想让多个单选框实现单选的效果，则多个单选框的name属性值必须一样。</li>
</ol>
</li>
<li><ol>
<li>一般会给每一个单选框提供value属性，指定其被选中后提交的值</li>
</ol>
</li>
<li><ol>
<li>checked属性，可以指定默认值</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>checkbox：复选框</p>
<ul>
<li><ul>
<li><p>注意：</p>
<ul>
<li><ol>
<li>一般会给每一个单选框提供value属性，指定其被选中后提交的值。</li>
</ol>
</li>
<li><ol>
<li>checked属性，可以指定默认值。</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li>file：文件选择框</li>
</ul>
</li>
<li><ul>
<li>hidden：隐藏域，用于提交一些信息。</li>
</ul>
</li>
<li><ul>
<li><p>按钮：</p>
<ul>
<li><ul>
<li>submit：提交按钮，可以提交表单</li>
</ul>
</li>
<li><ul>
<li>button：普通按钮</li>
</ul>
</li>
<li><ul>
<li><p>image：图片提交按钮</p>
<ul>
<li><ul>
<li>src属性指定图片的路径    </li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>label：指定输入项的文字描述信息</p>
<ul>
<li><ul>
<li><p>注意：</p>
<ul>
<li><ul>
<li>label的for属性一般会和 input 的 id属性值 对应。如果对应了，则点击label区域，会让input输入框获取焦点。</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>select: 下拉列表</p>
<ul>
<li><ul>
<li>子元素：option，指定列表项</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>textarea：文本域</p>
<ul>
<li><ul>
<li>cols：指定列数，每一行有多少个字符</li>
</ul>
</li>
<li><ul>
<li>rows：默认多少行。</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>代码</p>
<ul>
<li>&lt;!DOCTYPE html&gt;<html lang="en">
<head>
<meta charset="UTF-8">
<title>表单标签</title>
</head>
<body>
<form action="#" method="get">
<label for="username"> 用户名 </label>：<input type="text" name="username" placeholder="请输入用户名" id="username"><br>
密码：<input type="password" name="password" placeholder="请输入密码"><br>
性别：<input type="radio" name="gender" value="male"> 男
<input type="radio" name="gender" value="female" checked> 女
<br>
爱好：<input type="checkbox" name="hobby" value="shopping"> 逛街
<input type="checkbox" name="hobby" value="java" checked> Java
<input type="checkbox" name="hobby" value="game"> 游戏<br>
图片：<input type="file" name="file"><br>
隐藏域：<input type="hidden" name="id" value="aaa"> <br>
取色器：<input type="color" name="color"><br>
生日：<input type="date" name="birthday"> <br>
生日：<input type="datetime-local" name="birthday"> <br>
邮箱：<input type="email" name="email"> <br>
年龄：<input type="number" name="age"> <br>
省份：<select name="province">
  <option value="">--请选择--</option>
  <option value="1">北京</option>
  <option value="2">上海</option>
  <option value="3" selected>陕西</option>
</select><br>
自我描述：
<textarea cols="20" rows="5" name="des"></textarea>
<br>
<input type="submit" value="登录">
<input type="button" value="一个按钮"><br>
<input type="image" src="img/regbtn.jpg">
</form>
</body>
</html>
</li>
</ul>
</li>
<li><p>注册页面</p>
<ul>
<li>&lt;!DOCTYPE html&gt;<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册页面</title>
</head>
<body>
<!--定义表单 form-->
<form action="#" method="post">
<table border="1" align="center" width="500">
  <tr>
      <td><label for="username">用户名</label></td>
      <td><input type="text" name="username" id="username"></td>
  </tr>
  <tr>
      <td><label for="password">密码</label></td>
      <td><input type="password" name="password" id="password"></td>
  </tr>
  <tr>
      <td><label for="email">Email</label></td>
      <td><input type="email" name="email" id="email"></td>
  </tr>
  <tr>
      <td><label for="name">姓名</label></td>
      <td><input type="text" name="name" id="name"></td>
  </tr>
  <tr>
      <td><label for="tel">手机号</label></td>
      <td><input type="text" name="tel" id="tel"></td>
  </tr>
  <tr>
      <td><label>性别</label></td>
      <td><input type="radio" name="gender" value="male"> 男
          <input type="radio" name="gender" value="female"> 女
      </td>
  </tr>
  <tr>
      <td><label for="birthday">出生日期</label></td>
      <td><input type="date" name="birthday" id="birthday"></td>
  </tr>
  <tr>
      <td><label for="checkcode">验证码</label></td>
      <td><input type="text" name="checkcode" id="checkcode">
          <img src="img/verify_code.jpg">
      </td>
  </tr>
  <tr>
      <td colspan="2" align="center"><input type="submit" value="注册"></td>
  </tr>
</table>
</form>
</body>
</html>

</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="第4节-CSS概述"><a href="#第4节-CSS概述" class="headerlink" title="第4节 CSS概述"></a>第4节 CSS概述</h3><ul>
<li><ol>
<li><p>概念：Cascading Style Sheets 层叠样式表</p>
<ul>
<li><ul>
<li>层叠：多个样式可以作用在同一个html的元素上，同时生效</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>好处：</p>
<ul>
<li><ol>
<li>功能强大</li>
</ol>
</li>
<li><ol>
<li><p>将内容展示和样式控制分离</p>
<ul>
<li><ul>
<li>降低耦合度。解耦</li>
</ul>
</li>
<li><ul>
<li>让分工协作更容易</li>
</ul>
</li>
<li><ul>
<li>提高开发效率</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>CSS的使用：CSS与html结合方式</p>
<ul>
<li><ol>
<li><p>内联样式</p>
<ul>
<li><ul>
<li>在标签内使用style属性指定css代码</li>
</ul>
</li>
<li><ul>
<li>如：<div style="color:red;">hello css</div></li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>内部样式</p>
<ul>
<li><ul>
<li>在head标签内，定义style标签，style标签的标签体内容就是css代码</li>
</ul>
</li>
<li><ul>
<li>如：</li>
</ul>
<ul>
<li><style><br>div{<br>color:blue;<br>}
</style><div>hello css</div>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>外部样式</p>
<ul>
<li><ol>
<li>定义css资源文件。</li>
</ol>
</li>
<li><ol>
<li>在head标签内，定义link标签，引入外部的资源文件</li>
</ol>
<ul>
<li><ul>
<li><p>如a.css文件：</p>
<ul>
<li>div{<br>color:green;<br>}<br><link rel="stylesheet" href="css/a.css"><div>hello css</div>
<div>hello css</div></li>
<li><ul>
<li><p>注意：</p>
<ul>
<li><ul>
<li>1、2、3种方式，css作用范围越来越大</li>
</ul>
</li>
<li><ul>
<li>1方式不常用，后期常用2,3</li>
</ul>
</li>
<li><ul>
<li><p>第3种格式可以写为：</p>
<ul>
<li><style>
@import "css/a.css";
</style>

</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
</ul>
<h3 id="第5节-CSS-选择器"><a href="#第5节-CSS-选择器" class="headerlink" title="第5节 CSS_选择器"></a>第5节 CSS_选择器</h3><ul>
<li><ol>
<li><p>css语法：</p>
<ul>
<li><ul>
<li><p>选择器：筛选具有相似特征的元素</p>
<ul>
<li><ul>
<li><p>格式：</p>
<ul>
<li>选择器 {<br>属性名1:属性值1;<br>属性名2:属性值2;<br>…<br>}</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>注意：</p>
<ul>
<li><ul>
<li>每一对属性需要使用；隔开，最后一对属性可以不加“;”。</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>选择器：筛选具有相似特征的元素</p>
<ul>
<li><ul>
<li><p>分类：</p>
<ul>
<li><ol>
<li><p>基础选择器</p>
<ul>
<li><ol>
<li>id选择器：选择具体的id属性值的元素。建议在一个html页面中id值唯一。</li>
</ol>
<ul>
<li><ul>
<li>语法：#id属性值{}</li>
</ul>
</li>
</ul>
</li>
<li><ol>
<li>元素选择器：选择具有相同标签名称的元素。</li>
</ol>
<ul>
<li><ul>
<li>语法： 标签名称{}</li>
</ul>
</li>
<li><ul>
<li>注意：id选择器优先级 高于 元素选择器</li>
</ul>
</li>
</ul>
</li>
<li><ol>
<li>类选择器：选择具有相同的class属性值的元素。</li>
</ol>
<ul>
<li><ul>
<li>语法：.class属性值{}</li>
</ul>
</li>
<li><ul>
<li>注意：类选择器选择器优先级 高于 元素选择器。</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><p>. 扩展选择器：</p>
<ul>
<li><ol>
<li><p>选择所有元素：</p>
<ul>
<li><ul>
<li>语法： *{}</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>并集选择器：</p>
<ul>
<li><ul>
<li>选择器1，选择器2{}</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>子选择器：筛选选择器1元素下的选择器2元素</p>
<ul>
<li><ul>
<li>语法：  选择器1 选择器2{}</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>父选择器：筛选选择器2的父元素选择器1</p>
<ul>
<li><ul>
<li>语法：  选择器1 &gt; 选择器2{}</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>属性选择器：选择元素名称，属性名=属性值的元素</p>
<ul>
<li><ul>
<li>语法：  元素名称[属性名=”属性值”]{}</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>伪类选择器：选择一些元素具有的状态</p>
<ul>
<li><ul>
<li>语法： 元素:状态{}</li>
</ul>
</li>
<li><ul>
<li><p>如： <a></p>
<ul>
<li><ul>
<li><p>状态：</p>
<ul>
<li><ul>
<li>link：初始化的状态</li>
</ul>
</li>
<li><ul>
<li>visited：被访问过的状态</li>
</ul>
</li>
<li><ul>
<li>active：正在访问状态</li>
</ul>
</li>
<li><ul>
<li>hover：鼠标悬浮状态</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><p>优先级</p>
<ul>
<li>内联样式，优先级1000</li>
<li>id选择器，优先级100</li>
<li>类和伪类，优先级10</li>
<li>元素选择器，优先级1</li>
<li>通配选择器，优先级0</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
<h3 id="第6节-CSS属性"><a href="#第6节-CSS属性" class="headerlink" title="第6节 CSS属性"></a>第6节 CSS属性</h3><ul>
<li><ol>
<li><p>属性</p>
<ul>
<li><ol>
<li><p>字体、文本</p>
<ul>
<li><ul>
<li>font-size：字体大小</li>
</ul>
</li>
<li><ul>
<li>color：文本颜色</li>
</ul>
</li>
<li><ul>
<li>text-align：对其方式</li>
</ul>
</li>
<li><ul>
<li>line-height：行高 </li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>背景</p>
<ul>
<li><ul>
<li>background：</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>边框</p>
<ul>
<li><ul>
<li>border：设置边框，符合属性</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>尺寸</p>
<ul>
<li><ul>
<li>width：宽度</li>
</ul>
</li>
<li><ul>
<li>height：高度</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>盒子模型</p>
<ul>
<li><ul>
<li>margin：外边距</li>
</ul>
</li>
<li><ul>
<li>padding：内边距</li>
</ul>
</li>
<li><ul>
<li>默认情况下，内边距会影响整个盒子的大小。</li>
</ul>
</li>
<li><ul>
<li>box-sizing: border-box;  设置盒子的属性，令width和height就是最终盒子的大小。</li>
</ul>
</li>
<li><ul>
<li>float：浮动</li>
</ul>
<ul>
<li><ul>
<li>left</li>
</ul>
</li>
<li><ul>
<li>right</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
</ul>
<h3 id="第7节-CSS-案例-注册页面"><a href="#第7节-CSS-案例-注册页面" class="headerlink" title="第7节 CSS_案例-注册页面"></a>第7节 CSS_案例-注册页面</h3><ul>
<li><p>&lt;!DOCTYPE html&gt;<br><html lang="en"><br>  <head></p>
<pre><code>  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;title&gt;注册页面&lt;/title&gt;
  &lt;style&gt;
      * &#123;
      margin: 0px;
      padding: 0px;
      box-sizing: border-box;
  &#125;

  body &#123;
      background: url(&quot;img/register_bg.png&quot;) no-repeat center;
      padding-top: 25px;
  &#125;

  .rg_layout &#123;
      width: 900px;
      height: 500px;
      border: 8px solid #EEEEEE;
      background-color: white;
      /*让div水平居中*/
      margin: auto;
  &#125;

  .rg_left &#123;
      /* border: 1px solid red; */
      float: left;
      margin: 15px;
  &#125;

  .rg_left&gt;p:first-child &#123;
      color: #FFD026;
      font-size: 20px;
  &#125;

  .rg_left&gt;p:last-child &#123;
      color: #A6A6A6;
      font-size: 20px;
  &#125;

  .rg_center &#123;
      float: left;
      /* border: 1px solid red; */
  &#125;

  .rg_right &#123;
      /* border: 1px solid red; */
      float: right;
      margin: 15px;
  &#125;

  .rg_right&gt;p:first-child &#123;
      font-size: 15px;
  &#125;

  .rg_right p a &#123;
      color: pink;
  &#125;

  .td_left &#123;
      width: 100px;
      text-align: right;
      height: 45px;
  &#125;

  .td_right &#123;
      padding-left: 50px;
  &#125;

  #username,
  #password,
  #email,
  #name,
  #tel,
  #birthday,
  #checkcode &#123;
      width: 251px;
      height: 32px;
      border: 1px solid #A6A6A6;
      /*设置边框圆角*/
      border-radius: 5px;
      padding-left: 10px;
  &#125;

  #checkcode &#123;
      width: 110px;
  &#125;

  #img_check &#123;
      height: 32px;
      vertical-align: middle;
  &#125;

  #btn_sub &#123;
      width: 150px;
      height: 40px;
      background-color: #FFD026;
      border: 1px solid #FFD026;
  &#125;
</code></pre><p>  &lt;/style&gt;<br>  &lt;/head&gt;</p>
  <body>
      <div class="rg_layout">
          <div class="rg_left">
              <p>新用户注册</p>
              <p>USER REGISTER</p>
          </div>
          <div class="rg_center">
              <div class="rg_form">
                  <!--定义表单 form-->
                  <form action="#" method="post">
                      <table>
                          <tr>
                              <td class="td_left"><label for="username">用户名</label></td>
                              <td class="td_right"><input type="text" name="username" id="username" placeholder="请输入用户名">
                              </td>
                          </tr>
                          <tr>
                              <td class="td_left"><label for="password">密码</label></td>
                              <td class="td_right"><input type="password" name="password" id="password" placeholder="请输入密码"></td>
                          </tr>
                          <tr>
                              <td class="td_left"><label for="email">Email</label></td>
                              <td class="td_right"><input type="email" name="email" id="email" placeholder="请输入邮箱"></td>
                          </tr>
                          <tr>
                              <td class="td_left"><label for="name">姓名</label></td>
                              <td class="td_right"><input type="text" name="name" id="name" placeholder="请输入姓名"></td>
                          </tr>
                          <tr>
                              <td class="td_left"><label for="tel">手机号</label></td>
                              <td class="td_right"><input type="text" name="tel" id="tel" placeholder="请输入手机号"></td>
                          </tr>
                          <tr>
                              <td class="td_left"><label>性别</label></td>
                              <td class="td_right">
                                  <input type="radio" name="gender" value="male"> 男
                                  <input type="radio" name="gender" value="female"> 女
                              </td>
                          </tr>
                          <tr>
                              <td class="td_left"><label for="birthday">出生日期</label></td>
                              <td class="td_right"><input type="date" name="birthday" id="birthday" placeholder="请输入出生日期">
                              </td>
                          </tr>
                          <tr>
                              <td class="td_left"><label for="checkcode">验证码</label></td>
                              <td class="td_right"><input type="text" name="checkcode" id="checkcode" placeholder="请输入验证码">
                                  <img id="img_check" src="img/verify_code.jpg">
                              </td>
                          </tr>
                          <tr>
                              <td colspan="2" align="center"><input type="submit" id="btn_sub" value="注册"></td>
                          </tr>
                      </table>
                  </form>
              </div>
          </div>
          <div class="rg_right">
              <p>已有账号?<a href="#">立即登录</a></p>
          </div>
      </div>
  </body>

</li>
</ul>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://goofyer.gitee.io/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E5%85%AD%E7%AB%A0HTML%E5%92%8CCSS/" data-id="cl403sxre001xf8vu2vzr5f3n" data-title="" class="article-share-link">Share</a>
      
      
      
    </footer>
  </div>
  
</article>



  
    <article id="post-Java/第十五章JavaWeb" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E4%BA%94%E7%AB%A0JavaWeb/" class="article-date">
  <time class="dt-published" datetime="2021-12-19T17:34:30.992Z" itemprop="datePublished">2021-12-20</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h2 id="第十五章JavaWeb"><a href="#第十五章JavaWeb" class="headerlink" title="第十五章JavaWeb"></a>第十五章JavaWeb</h2>
      
    </div>
    <footer class="article-footer">
      <a data-url="https://goofyer.gitee.io/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E4%BA%94%E7%AB%A0JavaWeb/" data-id="cl403sxrd001vf8vuedc4gvj8" data-title="" class="article-share-link">Share</a>
      
      
      
    </footer>
  </div>
  
</article>



  
    <article id="post-Java/第十四章JDBC" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E5%9B%9B%E7%AB%A0JDBC/" class="article-date">
  <time class="dt-published" datetime="2021-12-19T17:33:29.544Z" itemprop="datePublished">2021-12-20</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h2 id="第十四章JDBC"><a href="#第十四章JDBC" class="headerlink" title="第十四章JDBC"></a>第十四章JDBC</h2><h3 id="01-JDBC快速入门"><a href="#01-JDBC快速入门" class="headerlink" title="01 JDBC快速入门"></a>01 JDBC快速入门</h3><ul>
<li><ol>
<li><p>概念：</p>
<ul>
<li>Java DataBase Connectivity  Java 数据库连接， Java语言操作数据库</li>
</ul>
</li>
</ol>
</li>
<li><ul>
<li><p>JDBC本质：</p>
<ul>
<li>其实是官方（sun公司）定义的一套操作所有关系型数据库的规则，即接口。各个数据库厂商去实现这套接口，提供数据库驱动jar包。我们可以使用这套接口（JDBC）编程，真正执行的代码是驱动jar包中的实现类。</li>
<li>Person 接口：eat()方法   Worker实现类      Person p = new Worker(); // 父类引用指向子类对象</li>
<li>p.eat(); // 会调用Worker()实现类的eat方法，产生多态调用</li>
<li>JDBC编程，以接口类型调用方法。导入驱动jar包后，真正执行的是驱动jar包实现类对应的实现方法。</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="2-快速入门："><a href="#2-快速入门：" class="headerlink" title="2. 快速入门："></a>2. 快速入门：</h3><ul>
<li><ul>
<li><p>步骤：</p>
<ul>
<li><ol>
<li><p>导入驱动jar包 mysql-connector-java-5.1.37-bin.jar</p>
<ul>
<li>1.复制mysql-connector-java-5.1.37-bin.jar到项目的libs目录下</li>
<li>2.右键—&gt;Add As Library</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li>注册驱动</li>
</ol>
</li>
<li><ol>
<li>获取数据库连接对象 Connection</li>
</ol>
</li>
<li><ol>
<li>定义sql</li>
</ol>
</li>
<li><ol>
<li>获取执行sql语句的对象 Statement</li>
</ol>
</li>
<li><ol>
<li>执行sql，接受返回结果</li>
</ol>
</li>
<li><ol>
<li>处理结果</li>
</ol>
</li>
<li><ol>
<li>释放资源</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>代码实现：</p>
<ul>
<li>/**</li>
</ul>
</li>
<li>JDBC快速入门<br>*/<br>public class JdbcDemo1 {<br>public static void main(String[] args) throws Exception {<pre><code>//1.导入驱动jar包
//2.注册驱动
Class.forName(&quot;com.mysql.jdbc.Driver&quot;); // 把类通过Class.forName()加载进内存
//3.获取数据库连接对象
Connection conn = DriverManager.getConnection(&quot;jdbc:mysql://localhost:3306/db3&quot;, &quot;root&quot;, &quot;root&quot;);
//4.定义sql语句
String sql = &quot;update account set balance = 2000 where id = 1&quot;;
//5.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
//6.执行sql
int count = stmt.executeUpdate(sql);
//7.处理结果
System.out.println(count);
//8.释放资源
stmt.close();
conn.close();
</code></pre>}<br>}</li>
</ul>
</li>
</ul>
<h3 id="3-详解各个对象："><a href="#3-详解各个对象：" class="headerlink" title="3. 详解各个对象："></a>3. 详解各个对象：</h3><ul>
<li><ol>
<li><p>DriverManager：驱动管理对象</p>
<ul>
<li><ul>
<li><p>功能：</p>
<ul>
<li><ol>
<li><p>注册驱动：告诉程序该使用哪一个数据库驱动jar包</p>
<ul>
<li>static void registerDriver(Driver driver) :注册与给定的驱动程序 DriverManager 。 </li>
<li><p>写代码使用：</p>
<ul>
<li>Class.forName(“com.mysql.jdbc.Driver”);</li>
</ul>
</li>
<li><p>通过查看源码发现：</p>
<ul>
<li><p>在com.mysql.jdbc.Driver类中存在静态代码块</p>
<ul>
<li>static {<br>try {<br>java.sql.DriverManager.registerDriver(new Driver());<br>} catch (SQLException E) {<br>throw new RuntimeException(“Can’t register driver!”);<br>}<br>}</li>
</ul>
</li>
</ul>
</li>
<li><p>注意：mysql5之后的驱动jar包可以省略注册驱动的步骤。</p>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>获取数据库连接</p>
<ul>
<li><ul>
<li>方法：static Connection getConnection(String url, String user, String password) </li>
</ul>
</li>
<li><ul>
<li>参数：</li>
</ul>
</li>
<li><ul>
<li>url：指定连接的路径</li>
</ul>
</li>
<li><ul>
<li>语法：jdbc:mysql://ip地址(域名):端口号/数据库名称</li>
</ul>
</li>
<li><ul>
<li>例子：jdbc:mysql://localhost:3306/db3</li>
</ul>
</li>
<li><ul>
<li>细节：如果连接的是本机mysql服务器，并且mysql服务默认端口是3306，则url可以简写为：jdbc:mysql:///数据库名称</li>
</ul>
</li>
<li><ul>
<li>user：用户名</li>
</ul>
</li>
<li><ul>
<li>password：密码</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>Connection：数据库连接对象</p>
<ul>
<li><ol>
<li><p>功能：</p>
<ul>
<li><ol>
<li>获取执行sql 的对象</li>
</ol>
<ul>
<li><ul>
<li>Statement createStatement()</li>
</ul>
</li>
<li><ul>
<li>PreparedStatement prepareStatement(String sql)  </li>
</ul>
</li>
</ul>
</li>
<li><ol>
<li>管理事务：</li>
</ol>
<ul>
<li><ul>
<li>开启事务：setAutoCommit(boolean autoCommit) ：调用该方法设置参数为false，即开启事务</li>
</ul>
</li>
<li><ul>
<li>提交事务：commit() </li>
</ul>
</li>
<li><ul>
<li>回滚事务：rollback() </li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>Statement：执行sql的对象</p>
<ul>
<li><ol>
<li><p>执行sql</p>
<ul>
<li><ol>
<li>boolean execute(String sql) ：可以执行任意的sql（了解）</li>
</ol>
</li>
<li><ol>
<li>int executeUpdate(String sql) ：执行DML(insert、update、delete)语句、DDL(create、alter、drop)语句</li>
</ol>
<ul>
<li><ul>
<li>返回值：影响的行数，可以通过这个影响的行数判断DML语句是否执行成功。返回值&gt;0，则执行成功；反之，则失败。</li>
</ul>
</li>
</ul>
</li>
<li><ol>
<li>ResultSet executeQuery(String sql) ：执行DQL（select）语句</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li>练习：</li>
</ol>
</li>
<li><ol>
<li>account表 添加一条记录</li>
</ol>
</li>
<li><ol>
<li>account表 修改记录</li>
</ol>
</li>
<li><ol>
<li>account表 删除一条记录</li>
</ol>
</li>
<li><p>代码：package cn.itcast.jdbc;</p>
<ul>
<li>/**</li>
</ul>
</li>
</ul>
</li>
</ol>
<ul>
<li>account表 添加一条记录 insert 语句<br>*/<br>public class JDBCDemo2 {<br>public static void main(String[] args) {<pre><code>Statement stmt = null;
Connection conn = null;
try &#123;
    //1. 注册驱动
    Class.forName(&quot;com.mysql.jdbc.Driver&quot;);
    //2. 定义sql
    String sql = &quot;insert into account values(null,&#39;王五&#39;,3000)&quot;;
    //3.获取Connection对象
    conn = DriverManager.getConnection(&quot;jdbc:mysql:///db3&quot;, &quot;root&quot;, &quot;root&quot;);
    //4.获取执行sql的对象 Statement
    stmt = conn.createStatement();
    //5.执行sql
    int count = stmt.executeUpdate(sql);//影响的行数
    //6.处理结果
    System.out.println(count);
    if (count &gt; 0) &#123;
        System.out.println(&quot;添加成功！&quot;);
    &#125; else &#123;
        System.out.println(&quot;添加失败！&quot;);
    &#125;
&#125; catch (ClassNotFoundException e) &#123;
    e.printStackTrace();
&#125; catch (SQLException e) &#123;
    e.printStackTrace();
&#125; finally &#123;
    //stmt.close();
    //7. 释放资源
    //避免空指针异常
    if (stmt != null) &#123;
        try &#123;
            stmt.close();
        &#125; catch (SQLException e) &#123;
            e.printStackTrace();
        &#125;
    &#125;
    if (conn != null) &#123;
        try &#123;
            conn.close();
        &#125; catch (SQLException e) &#123;
            e.printStackTrace();
        &#125;
    &#125;
&#125;
</code></pre>}<br>}<br>JDBC练习_update语句<br>account表 修改记录</li>
</ul>
</li>
</ul>
<p>package cn.itcast.jdbc;</p>
<p>import java.sql.Connection;<br>import java.sql.DriverManager;<br>import java.sql.SQLException;<br>import java.sql.Statement;</p>
<p>/**</p>
<ul>
<li>account表 修改记录<br>*/<br>public class JDBCDemo3 {<br> public static void main(String[] args) {<pre><code> Connection conn = null;
 Statement stmt = null;
 try &#123;
     //1.注册驱动
     Class.forName(&quot;com.mysql.jdbc.Driver&quot;);
     //2.获取连接对象
     conn = DriverManager.getConnection(&quot;jdbc:mysql:///db3&quot;, &quot;root&quot;, &quot;root&quot;);
     //3.定义sql
     String sql = &quot;update account set balance = 1500 where id = 3&quot;;
     //4.获取执行sql对象
     stmt = conn.createStatement();
     //5.执行sql
     int count = stmt.executeUpdate(sql);
     //6.处理结果
     System.out.println(count);
     if (count &gt; 0) &#123;
         System.out.println(&quot;修改成功！&quot;);
     &#125; else &#123;
         System.out.println(&quot;修改失败！&quot;);
     &#125;
 &#125; catch (ClassNotFoundException e) &#123;
     e.printStackTrace();
 &#125; catch (SQLException e) &#123;
     e.printStackTrace();
 &#125; finally &#123;
     //7.释放资源
     if (stmt != null) &#123;
         try &#123;
             stmt.close();
         &#125; catch (SQLException e) &#123;
             e.printStackTrace();
         &#125;
     &#125;
     if (conn != null) &#123;
         try &#123;
             conn.close();
         &#125; catch (SQLException e) &#123;
             e.printStackTrace();
         &#125;
     &#125;
 &#125;
</code></pre> }<br>}<br>JDBC练习_update、DDL语句<br>account表 删除一条记录</li>
</ul>
<p>package cn.itcast.jdbc;</p>
<p>import cn.itcast.util.JDBCUtils;</p>
<p>import java.sql.Connection;<br>import java.sql.DriverManager;<br>import java.sql.SQLException;<br>import java.sql.Statement;</p>
<p>/**</p>
<ul>
<li>account表 删除一条记录<br>*/<br>public class JDBCDemo4 {<br> public static void main(String[] args) {<pre><code> Connection conn = null;
 Statement stmt = null;
 try &#123;
     //1. 注册驱动
     Class.forName(&quot;com.mysql.jdbc.Driver&quot;);
     //2.获取连接对象
     conn = DriverManager.getConnection(&quot;jdbc:mysql:///db3&quot;, &quot;root&quot;, &quot;root&quot;);
     //conn = JDBCUtils.getConnection(&quot;jdbc:mysql:///db3&quot;, &quot;root&quot;, &quot;root&quot;);
     //3.定义sql
     String sql = &quot;delete from account where id = 3&quot;;
     //4.获取执行sql对象
     stmt = conn.createStatement();
     //5.执行sql
     int count = stmt.executeUpdate(sql);
     //6.处理结果
     System.out.println(count);
     if (count &gt; 0) &#123;
         System.out.println(&quot;删除成功！&quot;);
     &#125; else &#123;
         System.out.println(&quot;删除失败！&quot;);
     &#125;
 &#125; catch (ClassNotFoundException e) &#123;
     e.printStackTrace();
 &#125; catch (SQLException e) &#123;
     e.printStackTrace();
 &#125; finally &#123;
     //7.释放资源
     if (stmt != null) &#123;
         try &#123;
             stmt.close();
         &#125; catch (SQLException e) &#123;
             e.printStackTrace();
         &#125;
     &#125;
     if (conn != null) &#123;
         try &#123;
             conn.close();
         &#125; catch (SQLException e) &#123;
             e.printStackTrace();
         &#125;
     &#125;
 &#125;
</code></pre> }<br>}<br>执行DDL语句</li>
</ul>
<p>package cn.itcast.jdbc;</p>
<p>import java.sql.Connection;<br>import java.sql.DriverManager;<br>import java.sql.SQLException;<br>import java.sql.Statement;</p>
<p>/**</p>
<ul>
<li>执行DDL语句<br>*/<br>public class JDBCDemo5 {<br> public static void main(String[] args) {<pre><code> Connection conn = null;
 Statement stmt = null;
 try &#123;
     //1. 注册驱动
     Class.forName(&quot;com.mysql.jdbc.Driver&quot;);
     //2.获取连接对象
     conn = DriverManager.getConnection(&quot;jdbc:mysql:///db3&quot;, &quot;root&quot;, &quot;root&quot;);
     //3.定义sql
     String sql = &quot;create table student (id int, name varchar(20))&quot;;
     //4.获取执行sql对象
     stmt = conn.createStatement();
     //5.执行sql
     int count = stmt.executeUpdate(sql);
     //6.处理结果
     System.out.println(count);
 &#125; catch (ClassNotFoundException e) &#123;
     e.printStackTrace();
 &#125; catch (SQLException e) &#123;
     e.printStackTrace();
 &#125; finally &#123;
     //7.释放资源
     if (stmt != null) &#123;
         try &#123;
             stmt.close();
         &#125; catch (SQLException e) &#123;
             e.printStackTrace();
         &#125;
     &#125;
     if (conn != null) &#123;
         try &#123;
             conn.close();
         &#125; catch (SQLException e) &#123;
             e.printStackTrace();
         &#125;
     &#125;
 &#125;
</code></pre> }<br>}<pre><code> - * 需求：不想传递参数（麻烦），还得保证工具类的通用性。
 - * 解决：配置文件
</code></pre></li>
</ul>
<ul>
<li><ol>
<li><p>ResultSet：结果集对象,封装查询结果</p>
<ul>
<li><ul>
<li>boolean next()：游标向下移动一行，判断当前行是否是最后一行末尾(是否有数据)；如果是，则返回false，如果不是则返回true。</li>
</ul>
</li>
<li><ul>
<li>getXxx(参数):获取数据</li>
</ul>
</li>
<li><ul>
<li>Xxx：代表数据类型   如：int getInt()、String getString()</li>
</ul>
</li>
<li><ul>
<li><p>参数：</p>
<ul>
<li><ol>
<li>int：代表列的编号，从1开始，如： getString(1)</li>
</ol>
</li>
<li><ol>
<li>String：代表列名称，如： getDouble(“balance”)</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>注意：</p>
<ul>
<li><ul>
<li><p>使用步骤：</p>
<ul>
<li><ol>
<li>游标向下移动一行</li>
</ol>
</li>
<li><ol>
<li>判断是否有数据</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>代码</p>
</li>
<li>/**</li>
</ul>
</li>
</ol>
<ul>
<li><p>执行DDL语句<br>*/<br>public class JDBCDemo6 {<br>public static void main(String[] args) {</p>
<pre><code>Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try &#123;
    //1. 注册驱动
    Class.forName(&quot;com.mysql.jdbc.Driver&quot;);
    //2.获取连接对象
    conn = DriverManager.getConnection(&quot;jdbc:mysql:///db3&quot;, &quot;root&quot;, &quot;root&quot;);
    //3.定义sql
    String sql = &quot;select * from account&quot;;
    //4.获取执行sql对象
    stmt = conn.createStatement();
    //5.执行sql
    rs = stmt.executeQuery(sql);
    //6.处理结果
    //6.1 让游标向下移动一行
    rs.next();
    //6.2 获取数据
    int id = rs.getInt(1);
    String name = rs.getString(&quot;name&quot;);
    double balance = rs.getDouble(3);
    System.out.println(id + &quot;---&quot; + name + &quot;---&quot; + balance);
&#125; catch (ClassNotFoundException e) &#123;
    e.printStackTrace();
&#125; catch (SQLException e) &#123;
    e.printStackTrace();
&#125; finally &#123;
    //7.释放资源
    if (rs != null) &#123;
        try &#123;
            rs.close();
        &#125; catch (SQLException e) &#123;
            e.printStackTrace();
        &#125;
    &#125;
    if (stmt != null) &#123;
        try &#123;
            stmt.close();
        &#125; catch (SQLException e) &#123;
            e.printStackTrace();
        &#125;
    &#125;
    if (conn != null) &#123;
        try &#123;
            conn.close();
        &#125; catch (SQLException e) &#123;
            e.printStackTrace();
        &#125;
    &#125;
&#125;
</code></pre><p>}<br>}</p>
<pre><code>- /**
</code></pre></li>
<li><p>封装Emp表数据的JavaBean<br>*/<br>public class Emp {<br>private int id;<br>private String ename;<br>private int job_id;<br>private int mgr;<br>private Date joindate;<br>private double salary;<br>private double bonus;<br>private int dept_id;</p>
<p>public int getId() {</p>
<pre><code>return id;
</code></pre><p>}</p>
<p>public void setId(int id) {</p>
<pre><code>this.id = id;
</code></pre><p>}</p>
<p>public String getEname() {</p>
<pre><code>return ename;
</code></pre><p>}</p>
<p>public void setEname(String ename) {</p>
<pre><code>this.ename = ename;
</code></pre><p>}</p>
<p>public int getJob_id() {</p>
<pre><code>return job_id;
</code></pre><p>}</p>
<p>public void setJob_id(int job_id) {</p>
<pre><code>this.job_id = job_id;
</code></pre><p>}</p>
<p>public int getMgr() {</p>
<pre><code>return mgr;
</code></pre><p>}</p>
<p>public void setMgr(int mgr) {</p>
<pre><code>this.mgr = mgr;
</code></pre><p>}</p>
<p>public Date getJoindate() {</p>
<pre><code>return joindate;
</code></pre><p>}</p>
<p>public void setJoindate(Date joindate) {</p>
<pre><code>this.joindate = joindate;
</code></pre><p>}</p>
<p>public double getSalary() {</p>
<pre><code>return salary;
</code></pre><p>}</p>
<p>public void setSalary(double salary) {</p>
<pre><code>this.salary = salary;
</code></pre><p>}</p>
<p>public int getDept_id() {</p>
<pre><code>return dept_id;
</code></pre><p>}</p>
<p>public void setDept_id(int dept_id) {</p>
<pre><code>this.dept_id = dept_id;
</code></pre><p>}</p>
<p>public double getBonus() {</p>
<pre><code>return bonus;
</code></pre><p>}</p>
<p>public void setBonus(double bonus) {</p>
<pre><code>this.bonus = bonus;
</code></pre><p>}</p>
<p>@Override<br>public String toString() {</p>
<pre><code>return &quot;Emp&#123;&quot; +
        &quot;id=&quot; + id +
        &quot;, ename=&#39;&quot; + ename + &#39;\&#39;&#39; +
        &quot;, job_id=&quot; + job_id +
        &quot;, mgr=&quot; + mgr +
        &quot;, joindate=&quot; + joindate +
        &quot;, salary=&quot; + salary +
        &quot;, bonus=&quot; + bonus +
        &quot;, dept_id=&quot; + dept_id +
        &#39;&#125;&#39;;
</code></pre><p>}<br>}<br>JDBCDemo8.java<br>package cn.itcast.jdbc;</p>
</li>
</ul>
</li>
</ul>
<p>import cn.itcast.domain.Emp;<br>import cn.itcast.util.JDBCUtils;</p>
<p>import java.sql.*;<br>import java.util.ArrayList;<br>import java.util.List;</p>
<p>/**</p>
<ul>
<li><ul>
<li><p>定义一个方法，查询emp表的数据将其封装为对象，然后装载集合，返回。<br>*/<br>public class JDBCDemo8 {</p>
<p>public static void main(String[] args) {<br>   List<Emp> list = new JDBCDemo8().findAll();<br>   System.out.println(list);<br>   System.out.println(list.size());<br>   for (Emp x : list) {</p>
<pre><code>   System.out.println(x);
</code></pre><p>   }<br>}</p>
<p>/**</p>
<ul>
<li>查询所有emp对象<br>*</li>
<li>@return<br>*/<br>public List<Emp> findAll() {<br> Connection conn = null;<br> Statement stmt = null;<br> ResultSet rs = null;<br> List<Emp> list = null;<br> try {<pre><code> //1.注册驱动
 Class.forName(&quot;com.mysql.jdbc.Driver&quot;);
 //2.获取连接
 conn = DriverManager.getConnection(&quot;jdbc:mysql:///db3&quot;, &quot;root&quot;, &quot;root&quot;);
 //3.定义sql
 String sql = &quot;select * from emp&quot;;
 //4.获取执行sql的对象
 stmt = conn.createStatement();
 //5.执行sql
 rs = stmt.executeQuery(sql);
 //6.遍历结果集，封装对象，装载集合
 Emp emp = null;
 list = new ArrayList&lt;Emp&gt;();
 while (rs.next()) &#123;
     //获取数据
     int id = rs.getInt(&quot;id&quot;);
     String ename = rs.getString(&quot;ename&quot;);
     int job_id = rs.getInt(&quot;job_id&quot;);
     int mgr = rs.getInt(&quot;mgr&quot;);
     Date joindate = rs.getDate(&quot;joindate&quot;);
     double salary = rs.getDouble(&quot;salary&quot;);
     double bonus = rs.getDouble(&quot;bonus&quot;);
     int dept_id = rs.getInt(&quot;dept_id&quot;);
     // 创建emp对象,并赋值
     emp = new Emp();
     emp.setId(id);
     emp.setEname(ename);
     emp.setJob_id(job_id);
     emp.setMgr(mgr);
     emp.setJoindate(joindate);
     emp.setSalary(salary);
     emp.setBonus(bonus);
     emp.setDept_id(dept_id);
     //装载集合
     list.add(emp);
 &#125;
</code></pre> } catch (ClassNotFoundException e) {<pre><code> e.printStackTrace();
</code></pre> } catch (SQLException e) {<pre><code> e.printStackTrace();
</code></pre> } finally {<pre><code> if (rs != null) &#123;
     try &#123;
         rs.close();
     &#125; catch (SQLException e) &#123;
         e.printStackTrace();
     &#125;
 &#125;
 if (stmt != null) &#123;
     try &#123;
         stmt.close();
     &#125; catch (SQLException e) &#123;
         e.printStackTrace();
     &#125;
 &#125;
 if (conn != null) &#123;
     try &#123;
         conn.close();
     &#125; catch (SQLException e) &#123;
         e.printStackTrace();
     &#125;
 &#125;
</code></pre> }<br> return list;<br>}</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>}</p>
<ul>
<li><p>抽取JDBC工具类 ： JDBCUtils</p>
<ul>
<li><ul>
<li>目的：简化书写</li>
</ul>
</li>
<li><ul>
<li><p>分析：</p>
<ul>
<li><ol>
<li>注册驱动也抽取</li>
</ol>
</li>
<li><ol>
<li><p>抽取一个方法获取连接对象</p>
<ul>
<li>jdbc.properties<br>url=…<br>user=…<br>password=…</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>抽取一个方法释放资源</p>
<ul>
<li><ul>
<li>代码实现：…</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>JDBC练习_登录案例</p>
<ul>
<li><ul>
<li><p>需求：</p>
<ul>
<li><ol>
<li>通过键盘录入用户名和密码</li>
</ol>
</li>
<li><ol>
<li><p>判断用户是否登录成功</p>
<ul>
<li><ul>
<li>select * from user where username = “” and password = “”;</li>
</ul>
</li>
<li><ul>
<li>如果这个sql有查询结果，则成功，反之，则失败</li>
</ul>
</li>
<li><ul>
<li><p>步骤：</p>
<ul>
<li><ol>
<li><p>创建数据库表 user</p>
<ul>
<li>CREATE TABLE USER(<br>id INT PRIMARY KEY AUTO_INCREMENT,<br>username VARCHAR(32),<br>PASSWORD VARCHAR(32)<br>);</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>INSERT INTO USER VALUES(NULL,’zhangsan’,’123’);<br>INSERT INTO USER VALUES(NULL,’lisi’,’234’);</p>
<ul>
<li><ol>
<li><p>代码实现：</p>
<ul>
<li>/**</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
<li>练习：</li>
<li><ul>
<li>需求：</li>
</ul>
</li>
<li><ol>
<li>通过键盘录入用户名和密码</li>
</ol>
</li>
<li><ol>
<li>判断用户是否登录成功<br>*/<br>public class JDBCDemo9 {</li>
</ol>
</li>
</ul>
<p>public static void main(String[] args) {<br>  //1.键盘录入，接受用户名和密码<br>  Scanner sc = new Scanner(System.in);<br>  System.out.println(“请输入用户名：”);<br>  String username = sc.nextLine();<br>  System.out.println(“请输入密码：”);<br>  String password = sc.nextLine();<br>  //2.调用方法 非静态方法，需要创建对象来调用<br>  boolean flag = new JDBCDemo9().login(username, password);<br>  //3.判断结果，输出不同语句<br>  if (flag) {</p>
<pre><code>  //登录成功
  System.out.println(&quot;登录成功！&quot;);
</code></pre><p>  } else {</p>
<pre><code>  System.out.println(&quot;用户名或密码错误！&quot;);
</code></pre><p>  }<br>}</p>
<p>/**</p>
<ul>
<li>登录方法<br>*/<br>public boolean login(String username, String password) {<br>if (username == null || password == null) {<pre><code>return false;
</code></pre>}<br>//连接数据库判断是否登录成功<br>Connection conn = null;<br>Statement stmt = null;<br>ResultSet rs = null;<br>//1.获取连接<br>try {<pre><code>conn = JDBCUtils.getConnection();
//2.定义sql
String sql = &quot;select * from user where username = &#39;&quot; + username + &quot;&#39; and password = &#39;&quot; + password + &quot;&#39; &quot;;
System.out.println(sql);
//3.获取执行sql的对象
stmt = conn.createStatement();
//4.执行查询
rs = stmt.executeQuery(sql);
//5.判断
</code></pre>   /* if(rs.next()){//如果有下一行，则返回true<pre><code>    return true;
&#125;else&#123;
    return false;
&#125;*/
return rs.next();//如果有下一行，则返回true
</code></pre>} catch (SQLException e) {<pre><code>e.printStackTrace();
</code></pre>} finally {<pre><code>JDBCUtils.close(rs, stmt, conn);
</code></pre>}<br>return false;<br>}</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>}</p>
<h3 id="5-PreparedStatement：执行sql的对象"><a href="#5-PreparedStatement：执行sql的对象" class="headerlink" title="5. PreparedStatement：执行sql的对象"></a>5. PreparedStatement：执行sql的对象</h3><ul>
<li><ol>
<li><p>SQL注入问题：在拼接sql时，有一些sql的特殊关键字参与字符串的拼接，会造成安全性问题。</p>
<ul>
<li><ol>
<li>输入用户随便，输入密码：a’ or ‘a’ = ‘a</li>
</ol>
</li>
<li><ol>
<li>sql：select * from user where username = ‘fhdsjkf’ and password = ‘a’ or ‘a’ = ‘a’ </li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li>解决sql注入问题：使用PreparedStatement对象来解决</li>
</ol>
</li>
<li><ol>
<li>预编译的SQL：参数使用?作为占位符</li>
</ol>
</li>
<li><ol>
<li><p>步骤：</p>
<ul>
<li><ol>
<li>导入驱动jar包 mysql-connector-java-5.1.37-bin.jar</li>
</ol>
</li>
<li><ol>
<li>注册驱动</li>
</ol>
</li>
<li><ol>
<li>获取数据库连接对象 Connection</li>
</ol>
</li>
<li><ol>
<li><p>定义sql</p>
<ul>
<li><ul>
<li>注意：sql的参数使用？作为占位符， 如：select * from user where username = ? and password = ?;</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li>获取执行sql语句的对象 PreparedStatement  Connection.prepareStatement(String sql) </li>
</ol>
</li>
<li><ol>
<li><p>给？赋值：</p>
<ul>
<li><ul>
<li>方法： setXxx(参数1,参数2)</li>
</ul>
<ul>
<li><ul>
<li>参数1：？的位置编号 从1 开始</li>
</ul>
</li>
<li><ul>
<li>参数2：？的值</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li>执行sql，接受返回结果，不需要传递sql语句</li>
</ol>
</li>
<li><ol>
<li>处理结果</li>
</ol>
</li>
<li><ol>
<li>释放资源</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>注意：后期都会使用PreparedStatement来完成增删改查的所有操作</p>
<ul>
<li><ol>
<li>可以防止SQL注入</li>
</ol>
</li>
<li><ol>
<li>效率更高</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><p>登录案例——解决sql注入问题</p>
<ul>
<li><p>/**</p>
<ul>
<li>练习：</li>
<li><ul>
<li>需求：</li>
</ul>
</li>
<li><ol>
<li>通过键盘录入用户名和密码</li>
</ol>
</li>
<li><ol>
<li>判断用户是否登录成功<br>*/<br>public class JDBCDemo9 {</li>
</ol>
</li>
</ul>
<p>public static void main(String[] args) {<br>  //1.键盘录入，接受用户名和密码<br>  Scanner sc = new Scanner(System.in);<br>  System.out.println(“请输入用户名：”);<br>  String username = sc.nextLine();<br>  System.out.println(“请输入密码：”);<br>  String password = sc.nextLine();<br>  //2.调用方法 非静态方法，需要创建对象来调用<br>  boolean flag = new JDBCDemo9().login(username, password);<br>  //3.判断结果，输出不同语句<br>  if (flag) {</p>
<pre><code>  //登录成功
  System.out.println(&quot;登录成功！&quot;);
</code></pre><p>  } else {</p>
<pre><code>  System.out.println(&quot;用户名或密码错误！&quot;);
</code></pre><p>  }<br>}</p>
<p>/**</p>
<ul>
<li>登录方法<br>*/<br>public boolean login(String username, String password) {<br>if (username == null || password == null) {<pre><code>return false;
</code></pre>}<br>//连接数据库判断是否登录成功<br>Connection conn = null;<br>Statement stmt = null;<br>ResultSet rs = null;<br>//1.获取连接<br>try {<pre><code>conn = JDBCUtils.getConnection();
//2.定义sql
String sql = &quot;select * from user where username = &#39;&quot; + username + &quot;&#39; and password = &#39;&quot; + password + &quot;&#39; &quot;;
System.out.println(sql);
//3.获取执行sql的对象
stmt = conn.createStatement();
//4.执行查询
rs = stmt.executeQuery(sql);
//5.判断
</code></pre>   /* if(rs.next()){//如果有下一行，则返回true<pre><code>    return true;
&#125;else&#123;
    return false;
&#125;*/
return rs.next();//如果有下一行，则返回true
</code></pre>} catch (SQLException e) {<pre><code>e.printStackTrace();
</code></pre>} finally {<pre><code>JDBCUtils.close(rs, stmt, conn);
</code></pre>}<br>return false;<br>}</li>
</ul>
<p>/**</p>
<ul>
<li>登录方法,使用PreparedStatement实现<br>*/<br>public boolean login2(String username, String password) {<br>if (username == null || password == null) {<pre><code>return false;
</code></pre>}<br>//连接数据库判断是否登录成功<br>Connection conn = null;<br>PreparedStatement pstmt = null;<br>ResultSet rs = null;<br>//1.获取连接<br>try {<pre><code>conn = JDBCUtils.getConnection();
//2.定义sql
String sql = &quot;select * from user where username = ? and password = ?&quot;;
//3.获取执行sql的对象
pstmt = conn.prepareStatement(sql);
//给?赋值
pstmt.setString(1, username);
pstmt.setString(2, password);
//4.执行查询,不需要传递sql
rs = pstmt.executeQuery();
//5.判断
</code></pre>   /* if(rs.next()){//如果有下一行，则返回true<pre><code>    return true;
&#125;else&#123;
    return false;
&#125;*/
return rs.next();//如果有下一行，则返回true
</code></pre>} catch (SQLException e) {<pre><code>e.printStackTrace();
</code></pre>} finally {<pre><code>JDBCUtils.close(rs, pstmt, conn);
</code></pre>}<br>return false;<br>}</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="6-JDBC事务管理"><a href="#6-JDBC事务管理" class="headerlink" title="6 JDBC事务管理"></a>6 JDBC事务管理</h3><ul>
<li><ol>
<li>事务：一个包含多个步骤的业务操作。如果这个业务操作被事务管理，则这多个步骤要么同时成功，要么同时失败。</li>
</ol>
</li>
<li><ol>
<li><p>操作：</p>
<ul>
<li><ol>
<li>开启事务</li>
</ol>
</li>
<li><ol>
<li>提交事务</li>
</ol>
</li>
<li><ol>
<li>回滚事务</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>使用Connection对象来管理事务</p>
<ul>
<li><ul>
<li><p>开启事务：setAutoCommit(boolean autoCommit) ：调用该方法设置参数为false，即开启事务</p>
<ul>
<li><ul>
<li>在执行sql之前开启事务</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>提交事务：commit() </p>
<ul>
<li><ul>
<li>当所有sql都执行完提交事务</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>回滚事务：rollback() </p>
<ul>
<li><ul>
<li>在catch中回滚事务</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>代码：</p>
<ul>
<li>/**</li>
</ul>
</li>
</ol>
<ul>
<li><p>事务操作——JDBC控制事务<br>*/<br>public class JDBCDemo10 {</p>
<p>public static void main(String[] args) {</p>
<pre><code>Connection conn = null;
PreparedStatement pstmt1 = null;
PreparedStatement pstmt2 = null;
try &#123;
    //1.获取连接
    conn = JDBCUtils.getConnection();
    //开启事务
    conn.setAutoCommit(false);
    //2.定义sql
    //2.1 张三 - 500
    String sql1 = &quot;update account set balance = balance - ? where id = ?&quot;;
    //2.2 李四 + 500
    String sql2 = &quot;update account set balance = balance + ? where id = ?&quot;;
    //3.获取执行sql对象
    pstmt1 = conn.prepareStatement(sql1);
    pstmt2 = conn.prepareStatement(sql2);
    //4. 设置参数
    pstmt1.setDouble(1, 500);
    pstmt1.setInt(2, 1);
    pstmt2.setDouble(1, 500);
    pstmt2.setInt(2, 2);
    //5.执行sql
    pstmt1.executeUpdate();
    // 手动制造异常
    int i = 3 / 0;
    pstmt2.executeUpdate();
    //提交事务
    conn.commit();
&#125; catch (Exception e) &#123; // 只要出现异常，就进行事务的回滚 捕捉大异常
    //事务回滚
    try &#123;
        if (conn != null) &#123;
            conn.rollback();
        &#125;
    &#125; catch (SQLException e1) &#123;
        e1.printStackTrace();
    &#125;
    e.printStackTrace();
&#125; finally &#123;
    JDBCUtils.close(pstmt1, conn);
    JDBCUtils.close(pstmt2, null);
&#125;
</code></pre><p>}</p>
</li>
</ul>
</li>
</ul>
<p>}</p>
<h3 id="08-数据库连接池"><a href="#08-数据库连接池" class="headerlink" title="08 数据库连接池"></a>08 数据库连接池</h3><ul>
<li><ol>
<li><p>概念：</p>
<ul>
<li>其实就是一个容器(集合)，存放数据库连接的容器。当系统初始化好后，容器被创建，容器中会申请一些连接对象，当用户来访问数据库时，从容器中获取连接对象，用户访问完之后，会将连接对象归还给容器。</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>好处：</p>
<ul>
<li><ol>
<li>节约资源</li>
</ol>
</li>
<li><ol>
<li>用户访问高效</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>实现：</p>
<ul>
<li><ol>
<li><p>标准接口：DataSource   javax.sql包下的</p>
<ul>
<li><ol>
<li>方法：</li>
</ol>
<ul>
<li><ul>
<li>获取连接：getConnection()</li>
</ul>
</li>
<li><ul>
<li>归还连接：Connection.close()  如果连接对象Connection是从连接池中获取的，那么调用Connection.close()方法，则不会再关闭连接了，而是归还连接。</li>
</ul>
</li>
</ul>
</li>
<li><ol>
<li>一般我们不去实现它，有数据库厂商来实现</li>
</ol>
<ul>
<li><ol>
<li>C3P0：数据库连接池技术</li>
</ol>
</li>
<li><ol>
<li>Druid：数据库连接池实现技术，由阿里巴巴提供的</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>C3P0：数据库连接池技术</p>
<ul>
<li><ul>
<li><p>步骤：</p>
<ul>
<li><ol>
<li><p>导入jar包 (两个) c3p0-0.9.5.2.jar、mchange-commons-java-0.2.12.jar ，</p>
<ul>
<li><ul>
<li>不要忘记导入数据库驱动jar包</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>定义配置文件：</p>
<ul>
<li><ul>
<li>名称： c3p0.properties 或者 c3p0-config.xml</li>
</ul>
</li>
<li><ul>
<li>路径：直接将文件放在src目录下即可。</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li>创建核心对象 数据库连接池对象 ComboPooledDataSource</li>
</ol>
</li>
<li><ol>
<li>获取连接： getConnection</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>代码：</p>
<ul>
<li>//1.创建数据库连接池对象<br>DataSource ds  = new ComboPooledDataSource();<br>//2. 获取连接对象<br>Connection conn = ds.getConnection();</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>Druid：数据库连接池实现技术，由阿里巴巴提供的。</p>
<ul>
<li><ol>
<li><p>步骤：</p>
<ul>
<li><ol>
<li>导入jar包 druid-1.0.9.jar</li>
</ol>
</li>
<li><ol>
<li>定义配置文件：</li>
</ol>
<ul>
<li><ul>
<li>是properties形式的</li>
</ul>
</li>
<li><ul>
<li>可以叫任意名称，可以放在任意目录下</li>
</ul>
</li>
</ul>
</li>
<li><ol>
<li>加载配置文件。Properties</li>
</ol>
</li>
<li><ol>
<li>获取数据库连接池对象：通过工厂来来获取  DruidDataSourceFactory</li>
</ol>
</li>
<li><ol>
<li>获取连接：getConnection</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ul>
<li><p>代码：</p>
<ul>
<li>/**</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
<ul>
<li><p>Druid演示<br>*/<br>public class DruidDemo {<br>public static void main(String[] args) throws Exception {</p>
<pre><code>//1.导入jar包
//2.定义配置文件
//3.加载配置文件
Properties pro = new Properties();
InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream(&quot;druid.properties&quot;);
pro.load(is);
//4.获取连接池对象
DataSource ds = DruidDataSourceFactory.createDataSource(pro);
//5.获取连接
Connection conn = ds.getConnection();
System.out.println(conn);
</code></pre><p>}<br>}</p>
<ul>
<li>/**</li>
</ul>
</li>
<li><p>Druid连接池的工具类<br>*/<br>public class JDBCUtils {</p>
<p>//1.定义成员变量 DataSource<br>private static DataSource ds ;</p>
<p>static{</p>
<pre><code>try &#123;
    //1.加载配置文件
    Properties pro = new Properties();
    pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream(&quot;druid.properties&quot;));
    //2.获取DataSource
    ds = DruidDataSourceFactory.createDataSource(pro);
&#125; catch (IOException e) &#123;
    e.printStackTrace();
&#125; catch (Exception e) &#123;
    e.printStackTrace();
&#125;
</code></pre><p>}</p>
<p>/**</p>
<ul>
<li>获取连接<br>*/<br>public static Connection getConnection() throws SQLException {<br> return ds.getConnection();<br>}</li>
</ul>
<p>/**</p>
<ul>
<li>释放资源<br><em>/<br>public static void close(Statement stmt,Connection conn){<br>/</em> if (stmt != null) {<pre><code> try &#123;
     stmt.close();
 &#125; catch (SQLException e) &#123;
     e.printStackTrace();
 &#125;
</code></pre> }<br> if (conn != null) {<pre><code> try &#123;
     conn.close();//归还连接
 &#125; catch (SQLException e) &#123;
     e.printStackTrace();
 &#125;
</code></pre> }*/<br>close(null,stmt,conn);<br>}</li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code>public static void close(ResultSet rs , Statement stmt, Connection conn)&#123;
    if(rs != null)&#123;
        try &#123;
            rs.close();
        &#125; catch (SQLException e) &#123;
            e.printStackTrace();
        &#125;
    &#125;
    if(stmt != null)&#123;
        try &#123;
            stmt.close();
        &#125; catch (SQLException e) &#123;
            e.printStackTrace();
        &#125;
    &#125;
    if(conn != null)&#123;
        try &#123;
            conn.close();//归还连接
        &#125; catch (SQLException e) &#123;
            e.printStackTrace();
        &#125;
    &#125;
&#125;

/**
 * 获取连接池方法
 */
public static DataSource getDataSource()&#123;
    return  ds;
&#125;
</code></pre><p>}<br>DruidDemo2.java<br>package cn.itcast.datasource.druid;</p>
<p>import cn.itcast.utils.JDBCUtils;</p>
<p>import java.sql.Connection;<br>import java.sql.PreparedStatement;<br>import java.sql.ResultSet;<br>import java.sql.SQLException;</p>
<p>/**</p>
<ul>
<li><p>使用新的工具类<br>*/<br>public class DruidDemo2 {</p>
<p> public static void main(String[] args) {</p>
</li>
</ul>
<p> //1.获取连接<br>            conn = JDBCUtils.getConnection();<br>            //2.定义sql<br>            String sql = “insert into account values(null, ?, ?)”; // 主键自增长<br>            //3.获取pstmt对象<br>            pstmt = conn.prepareStatement(sql);<br>            //4.给？赋值<br>            pstmt.setString(1, “王五”);<br>            pstmt.setDouble(2, 3001);<br>            //5.执行sql<br>            int count = pstmt.executeUpdate();<br>            System.out.println(count);<br>        } catch (SQLException e) {<br>            e.printStackTrace();<br>        } finally {<br>            //6. 释放资源<br>            JDBCUtils.close(pstmt, conn);<br>        }<br>    }</p>
<h3 id="09-JDBCTemplate"><a href="#09-JDBCTemplate" class="headerlink" title="09 JDBCTemplate"></a>09 JDBCTemplate</h3><ul>
<li><p>JDBCTemplate_介绍</p>
<ul>
<li><ul>
<li>Spring框架对JDBC的简单封装，提供了一个JDBCTemplate对象简化JDBC的开发。</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>步骤：</p>
<ul>
<li><ol>
<li>导入jar包</li>
</ol>
</li>
<li><ol>
<li><p>创建JdbcTemplate对象（依赖于数据源DataSource）</p>
<ul>
<li><ul>
<li>JdbcTemplate template = new JdbcTemplate(ds);</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>调用JdbcTemplate的方法来完成CRUD的操作</p>
<ul>
<li><ul>
<li>update()：执行DML语句（增、删、改语句）。</li>
</ul>
</li>
<li><ul>
<li>queryForMap()：查询结果将结果集封装为map集合。</li>
</ul>
</li>
<li><ul>
<li>queryForList()：查询结果将结果集封装为list集合。</li>
</ul>
</li>
<li><ul>
<li>query()：查询结果，将结果封装为JavaBean对象。</li>
</ul>
</li>
<li><ul>
<li>queryForObject：查询结果，将结果封装为对象。</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>练习：</p>
<ul>
<li><ul>
<li><p>需求：</p>
<ul>
<li><ol>
<li>修改1号数据的 salary 为 10000</li>
</ol>
</li>
<li><ol>
<li>添加一条记录</li>
</ol>
</li>
<li><ol>
<li>删除刚才添加的记录</li>
</ol>
</li>
<li><ol>
<li>查询id为1的记录，将其封装为Map集合</li>
</ol>
</li>
<li><ol>
<li>查询所有记录，将其封装为List</li>
</ol>
</li>
<li><ol>
<li>查询所有记录，将其封装为Emp对象的List集合</li>
</ol>
</li>
<li><ol>
<li>查询总记录数</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>代码：</p>
<ul>
<li><ol>
<li><p>修改1号数据的 salary 为 10000</p>
<ul>
<li>子主题 1</li>
<li>子主题 2</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>添加一条记录</p>
<ul>
<li>子主题 1</li>
</ul>
</li>
</ol>
</li>
<li><p>3.删除刚才添加的记录</p>
<ul>
<li>子主题 1</li>
</ul>
</li>
<li><p>JUnit 代码</p>
<ul>
<li>public class JdbcTemplateDemo2 {</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
<p>//Junit单元测试，可以让方法独立执行</p>
<p>//1. 获取JDBCTemplate对象<br>private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());</p>
<p>/**</p>
<ul>
<li>Junit单元测试，可以让方法独立执行<br>*/<br>@Test<br>public void test() {<br> System.out.println(“我被执行了…”);<br> int i = 3 / 0;<br> System.out.println(“我被执行了…”);<br>}</li>
</ul>
<p>/**</p>
<ul>
<li><ol>
<li>修改1号数据的 salary 为 10000<br>*/<br>@Test<br>public void test1() {<br>//2. 定义sql<br>String sql = “update emp set salary = 10000 where id = 1001”;<br>//3. 执行sql<br>int count = template.update(sql);<br>System.out.println(count);<br>}</li>
</ol>
</li>
</ul>
<p>/**</p>
<ul>
<li><ol>
<li>添加一条记录<br>*/<br>@Test<br>public void test2() {<br>String sql = “insert into emp(id,ename,dept_id) values(?,?,?)”;<br>int count = template.update(sql, 1015, “郭靖”, 10);<br>System.out.println(count);<br>}</li>
</ol>
</li>
</ul>
<p>/**</p>
<ul>
<li>3.删除刚才添加的记录<br>*/<br>@Test<br>public void test3() {<br> String sql = “delete from emp where id = ?”;<br> int count = template.update(sql, 1015);<br> System.out.println(count);<br>}</li>
</ul>
<p>/**</p>
<ul>
<li>4.查询id为1001的记录，将其封装为Map集合</li>
<li>注意：这个方法查询的结果集长度只能是1<br><em>/<br>@Test<br>public void test4() {<br> String sql = “select </em> from emp where id = ? or id = ?”;<br> Map<String, Object> map = template.queryForMap(sql, 1001);<br> // Map<String, Object> map = template.queryForMap(sql, 1001, 1002); // 错误<br> System.out.println(map);<br> // {id=1001, ename=孙悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20}<br>}</li>
</ul>
<p>/**</p>
<ul>
<li><ol>
<li>查询所有记录，将其封装为List<br><em>/<br>@Test<br>public void test5() {<br>String sql = “select </em> from emp”;<br>List<Map<String, Object>&gt; list = template.queryForList(sql);<br>for (Map<String, Object> stringObjectMap : list) {<br>  System.out.println(stringObjectMap);<br>}<br>}</li>
</ol>
</li>
</ul>
<p>/**</p>
<ul>
<li><ol>
<li>查询所有记录，将其封装为Emp对象的List集合<br><em>/<br>@Test<br>public void test6() {<br>String sql = “select </em> from emp”;<br>List<Emp> list = template.query(sql, new RowMapper<Emp>() {<br>  @Override<br>  public Emp mapRow(ResultSet rs, int i) throws SQLException {<pre><code>  Emp emp = new Emp();
  int id = rs.getInt(&quot;id&quot;);
  String ename = rs.getString(&quot;ename&quot;);
  int job_id = rs.getInt(&quot;job_id&quot;);
  int mgr = rs.getInt(&quot;mgr&quot;);
  Date joindate = rs.getDate(&quot;joindate&quot;);
  double salary = rs.getDouble(&quot;salary&quot;);
  double bonus = rs.getDouble(&quot;bonus&quot;);
  int dept_id = rs.getInt(&quot;dept_id&quot;);
  emp.setId(id);
  emp.setEname(ename);
  emp.setJob_id(job_id);
  emp.setMgr(mgr);
  emp.setJoindate(joindate);
  emp.setSalary(salary);
  emp.setBonus(bonus);
  emp.setDept_id(dept_id);
  return emp;
</code></pre>  }<br>});<br>for (Emp emp : list) {<br>  System.out.println(emp);<br>}<br>}</li>
</ol>
</li>
</ul>
<p>/**</p>
<ul>
<li><ol>
<li>查询所有记录，将其封装为Emp对象的List集合<br><em>/<br>@Test<br>public void test6_2() {<br>String sql = “select </em> from emp”;<br>List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));<br>for (Emp emp : list) {<br>  System.out.println(emp);<br>}<br>}</li>
</ol>
</li>
</ul>
<p>/**</p>
<ul>
<li><ol>
<li>查询总记录数<br>*/<br>@Test<br>public void test7() {<br>String sql = “select count(id) from emp”;<br>Long total = template.queryForObject(sql, Long.class);<br>System.out.println(total);<br>}</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>}</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://goofyer.gitee.io/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E5%9B%9B%E7%AB%A0JDBC/" data-id="cl403sxre001yf8vu0lub8z4c" data-title="" class="article-share-link">Share</a>
      
      
      
    </footer>
  </div>
  
</article>



  
    <article id="post-Java/第十三章MySQL" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E4%B8%89%E7%AB%A0MySQL/" class="article-date">
  <time class="dt-published" datetime="2021-12-19T17:33:22.655Z" itemprop="datePublished">2021-12-20</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h2 id="第十三章MySQL"><a href="#第十三章MySQL" class="headerlink" title="第十三章MySQL"></a>第十三章MySQL</h2><h3 id="01-数据库概念"><a href="#01-数据库概念" class="headerlink" title="01 数据库概念"></a>01 数据库概念</h3><ul>
<li><p>数据库的基本概念</p>
<ul>
<li><ol>
<li>数据库的英文单词： DataBase 简称 ： DB</li>
</ol>
</li>
<li><ol>
<li><p>什么数据库？</p>
<ul>
<li>用于存储和管理数据的仓库。</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>数据库的特点：</p>
<ul>
<li><ol>
<li>持久化存储数据的。其实数据库就是一个文件系统</li>
</ol>
</li>
<li><ol>
<li>方便存储和管理数据</li>
</ol>
</li>
<li><ol>
<li>使用了统一的方式操作数据库 — SQL</li>
</ol>
</li>
<li><ol>
<li><p>常见的数据库软件</p>
<ul>
<li><ul>
<li>参见《MySQL基础.pdf》</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
<h3 id="02-MySQL安装与使用"><a href="#02-MySQL安装与使用" class="headerlink" title="02 MySQL安装与使用"></a>02 MySQL安装与使用</h3><ul>
<li><p>MySQL数据库软件</p>
<ul>
<li><ol>
<li><p>安装</p>
<ul>
<li><ul>
<li>参见《MySQL基础.pdf》</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>卸载</p>
<ul>
<li><ol>
<li><p>去mysql的安装目录找到my.ini文件</p>
<ul>
<li><ul>
<li>复制 datadir=”C:/ProgramData/MySQL/MySQL Server 5.5/Data/“</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li>卸载MySQL</li>
</ol>
</li>
<li><ol>
<li>删除C:/ProgramData目录下的MySQL文件夹。</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>配置</p>
<ul>
<li><p>①* MySQL服务启动</p>
<ul>
<li><ol>
<li>手动。</li>
</ol>
</li>
<li><ol>
<li>cmd—&gt; services.msc 打开服务的窗口</li>
</ol>
</li>
<li><ol>
<li><p>使用管理员打开cmd</p>
<ul>
<li><ul>
<li>net start mysql : 启动mysql的服务</li>
</ul>
</li>
<li><ul>
<li>net stop mysql:关闭mysql服务</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
<li><p>②* MySQL登录</p>
<ul>
<li><ol>
<li>mysql -uroot -p密码</li>
</ol>
</li>
<li><ol>
<li>mysql -hip -uroot -p连接目标的密码</li>
</ol>
</li>
<li><ol>
<li>mysql —host=ip —user=root —password=连接目标的密码</li>
</ol>
</li>
</ul>
</li>
<li><p>③* MySQL退出</p>
<ul>
<li><ol>
<li>exit</li>
</ol>
</li>
<li><ol>
<li>quit</li>
</ol>
</li>
</ul>
</li>
<li><p>④* MySQL目录结构</p>
<ul>
<li><ol>
<li><p>MySQL安装目录：basedir=”D:/develop/MySQL/“</p>
<ul>
<li><ul>
<li>配置文件 my.ini</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
<li><ol>
<li><p>MySQL数据目录：datadir=”C:/ProgramData/MySQL/MySQL Server 5.5/Data/“</p>
<ul>
<li><ul>
<li>几个概念</li>
</ul>
</li>
<li><ul>
<li>数据库：文件夹</li>
</ul>
</li>
<li><ul>
<li>表：文件</li>
</ul>
</li>
<li><ul>
<li>数据：数据</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><p>MySQL安装目录</p>
<ul>
<li>bin目录：存放二进制的可执行文件（mysql.exe：登录MySQL服务器的命令）。</li>
<li>data目录：数据目录，存放MySQL的数据文件、日志文件。</li>
<li>include目录：C语言的头信息。</li>
<li>lib目录：MySQL需要的一些jar包、运行需要的库文件。</li>
<li>share目录：存放mysql的一些错误信息。</li>
<li>my.ini：mysql的配置文件。</li>
</ul>
</li>
</ul>
<h3 id="03-SQL基本概念与通用语法"><a href="#03-SQL基本概念与通用语法" class="headerlink" title="03 SQL基本概念与通用语法"></a>03 SQL基本概念与通用语法</h3><ul>
<li><p>1.什么是SQL？</p>
<ul>
<li>Structured Query Language：结构化查询语言</li>
<li>其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式存在不一样的地方，称为“方言”。</li>
</ul>
</li>
<li><p>2.SQL通用语法</p>
<ul>
<li><ol>
<li>SQL 语句可以单行或多行书写，以分号结尾。</li>
</ol>
</li>
<li><ol>
<li>可使用空格和缩进来增强语句的可读性。</li>
</ol>
</li>
<li><ol>
<li>MySQL 数据库的 SQL 语句不区分大小写，关键字建议使用大写。</li>
</ol>
</li>
<li><ol>
<li><p>3 种注释</p>
<ul>
<li>单行注释: — 注释内容 或 # 注释内容(mysql 特有) </li>
<li>多行注释: /<em> 注释 </em>/</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
<li><ol>
<li><p>SQL分类</p>
<ul>
<li><p>1) DDL(Data Definition Language)数据定义语言</p>
<ul>
<li>用来定义数据库对象：数据库，表，列等。关键字：create, drop,alter 等</li>
</ul>
</li>
<li><p>2) DML(Data Manipulation Language)数据操作语言</p>
<ul>
<li>用来对数据库中表的数据进行增删改。关键字：insert, delete, update 等</li>
</ul>
</li>
<li><p>3) DQL(Data Query Language)数据查询语言</p>
<ul>
<li>用来查询数据库中表的记录(数据)。关键字：select, where 等</li>
</ul>
</li>
<li><p>4) DCL(Data Control Language)数据控制语言(了解)</p>
<ul>
<li>用来定义数据库的访问权限和安全级别，及创建用户。关键字：GRANT， REVOKE 等</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><p>SQL通用语法</p>
</li>
</ul>
<h3 id="04-数据库的CRUD操作"><a href="#04-数据库的CRUD操作" class="headerlink" title="04 数据库的CRUD操作"></a>04 数据库的CRUD操作</h3><ul>
<li><p>SQL分类</p>
<ul>
<li><p>DDL_操作数据库_创建&amp;查询</p>
<ul>
<li>1) DDL(Data Definition Language)数据定义语言：用来定义数据库对象：数据库，表，列等。关键字：create, drop,alter 等。</li>
<li>2) DML(Data Manipulation Language)数据操作语言：用来对数据库中表的数据进行增删改。关键字：insert, delete, update 等。</li>
<li>3) DQL(Data Query Language)数据查询语言：用来查询数据库中表的记录(数据)。关键字：select, where 等。</li>
<li>4) DCL(Data Control Language)数据控制语言(了解)：用来定义数据库的访问权限和安全级别，及创建用户。关键字：GRANT， REVOKE 等。</li>
</ul>
</li>
<li><ol>
<li><p>操作数据库：CRUD</p>
<ul>
<li><ol>
<li><p>C(Create)：创建</p>
<ul>
<li><ul>
<li>创建数据库：create database 数据库名称;</li>
</ul>
</li>
<li><ul>
<li>创建数据库，判断不存在，再创建：create database if not exists 数据库名称;</li>
</ul>
</li>
<li><ul>
<li>创建数据库，并指定字符集：create database 数据库名称 character set 字符集名;</li>
</ul>
</li>
<li><ul>
<li>练习： 创建db4数据库，判断是否存在，并制定字符集为gbk：create database if not exists db4 character set gbk;</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>R(Retrieve)：查询</p>
<ul>
<li><ul>
<li>查询所有数据库的名称：show databases;</li>
</ul>
</li>
<li><ul>
<li>查询某个数据库的字符集（查询某个数据库的创建语句）：show create database 数据库名称;</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>U(Update)：修改</p>
<ul>
<li><ul>
<li>修改数据库的字符集：alter database 数据库名称 character set 字符集名称;</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>D(Delete)：删除</p>
<ul>
<li><ul>
<li>删除数据库：drop database 数据库名称;</li>
</ul>
</li>
<li><ul>
<li>判断数据库存在，存在再删除：drop database if exists 数据库名称;</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>使用数据库</p>
<ul>
<li><ul>
<li>查询当前正在使用的数据库名称：select database();</li>
</ul>
</li>
<li><ul>
<li>使用数据库：use 数据库名称;</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><p>information_schema：描述MySQL数据库信息（有哪些表、有哪些库的名字）。此库中的数据库、数据表，并不是真正的数据库、数据表（视图），并不存在真正的目的文件。</p>
</li>
<li>mysql：MySQL核心数据库，存放着很多的核心数据。</li>
<li>performance_schema：对性能提升做操作的数据库。【information_schema、mysql、performance_schema 这三个数据库，尽量不要碰！】</li>
<li>test：测试数据库，空数据库，可以任意使用。</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
<h3 id="05-数据库表的CRUD操作"><a href="#05-数据库表的CRUD操作" class="headerlink" title="05 数据库表的CRUD操作"></a>05 数据库表的CRUD操作</h3><ul>
<li><p>数据字段类型</p>
<ul>
<li>int：整数类型【age int】</li>
<li>double：小数类型【score double(5, 2)  最多5位, 保留2位小数】</li>
<li>date：日期，只包含 年月日，yyyy-MM-dd</li>
<li>datetime：日期，包含年月日时分秒 yyyy-MM-dd HH:mm:ss</li>
<li>timestamp：时间戳类型，包含年月日时分秒，yyyy-MM-dd HH:mm:ss【如果将来不给这个字段赋值，或赋值为null，则默认使用当前的系统时间来自动赋值。】</li>
<li>varchar：字符串【name varchar(20)：姓名最大20个字符；zhangsan 8个字符、张三 2个字符】</li>
</ul>
</li>
<li><p>DDL_操作表_查询</p>
<ul>
<li><p>R(Retrieve)：查询</p>
<ul>
<li>查询某个数据库中所有的表名称：show tables;</li>
<li>查询表结构：desc 表名;（description）</li>
</ul>
</li>
</ul>
</li>
<li><p>表创建</p>
<ul>
<li>create table 表名(<br>列名1 数据类型1,<br>列名2 数据类型2,<br>…<br>列名n 数据类型n<br>);</li>
</ul>
</li>
<li><p>复制表</p>
<ul>
<li>create table 表名 like 被复制的表名;</li>
</ul>
</li>
<li><p>DDL_操作表_修改</p>
<ul>
<li>修改表名：alter table 表名 rename to 新的表名;</li>
<li>修改表的字符集：alter table 表名 character set 字符集名称;</li>
<li>添加一列：alter table 表名 add 列名 数据类型;</li>
<li>修改列名称 类型：alter table 表名 change 列名 新列名 新数据类型;   alter table 表名 modify 列名 新数据类型;</li>
<li>删除列：alter table 表名 drop 列名;</li>
<li>修改表名：alter table 表名 rename to 新的表名;</li>
</ul>
</li>
<li><p>DDL_操作表_删除</p>
<ul>
<li>drop table 表名;</li>
<li>drop table  if exists 表名 ;</li>
</ul>
</li>
<li><p>例子</p>
<ul>
<li><p>创建表</p>
<ul>
<li>create table student(<br>id int,<br>name varchar(32),<br>age int,<br>score double(4,1),<br>birthday date,<br>insert_time timestamp<br>);</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="06-数据库表中记录的基本操作"><a href="#06-数据库表中记录的基本操作" class="headerlink" title="06 数据库表中记录的基本操作"></a>06 数据库表中记录的基本操作</h3><ul>
<li><p>DML_添加数据</p>
<ul>
<li>语法：insert into 表名(列名1,列名2,…列名n) values(值1,值2,…值n);</li>
<li><p>注意：</p>
<ul>
<li>列名和值要一一对应。</li>
<li>如果表名后，不定义列名，则默认给所有列添加值【insert into 表名 values(值1,值2,…值n);】</li>
<li>除了数字类型，其他类型需要使用引号(单双都可以)引起来。</li>
</ul>
</li>
</ul>
</li>
<li><p>DML_删除数据</p>
<ul>
<li>语法：delete from 表名 [where 条件]</li>
<li><p>注意：</p>
<ul>
<li>如果不加条件，则删除表中所有记录。</li>
<li>如果要删除所有记录</li>
<li>delete from 表名; — 不推荐使用。有多少条记录就会执行多少次删除操作（效率低）。</li>
<li>TRUNCATE TABLE 表名; —（推荐使用，效率更高）先删除表，然后再创建一张一样的表。</li>
</ul>
</li>
</ul>
</li>
<li><p>DML_修改数据</p>
<ul>
<li>语法：update 表名 set 列名1 = 值1, 列名2 = 值2,… [where 条件];</li>
<li>注意：如果不加任何条件，则会将表中所有记录全部修改。</li>
</ul>
</li>
<li><p>数据库 终端 操作 报错</p>
<ul>
<li><p>报错的命令：ERROR 1366 (HY000): Incorrect string value: ‘\xC3\xFB\xD7\xD6’ for column ‘n</p>
<ul>
<li>解决方法（原文链接）：<a target="_blank" rel="noopener" href="https://blog.csdn.net/u013317172/article/details/82778785">https://blog.csdn.net/u013317172/article/details/82778785</a></li>
</ul>
</li>
<li><p>ERROR 1366 (HY000): Incorrect string value: ‘\xD5\xC5\xD0\xA1\xC3\xF7’ for column ‘NAME’ at row 1</p>
<ul>
<li><p>解决方案：</p>
<ul>
<li>1.先找到Mysql数据库安装路径，如下图：</li>
<li>2.找到这个文件夹里面的 my.ini 文件，在里面找到 “default-character-set=utf8”，把uft8修改成gbk。</li>
<li>重新登陆到mysql数据库就可以添加中文数据了。</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="07-数据库的查询操作"><a href="#07-数据库的查询操作" class="headerlink" title="07 数据库的查询操作"></a>07 数据库的查询操作</h3><ul>
<li>— 查询年龄大于20岁<br>SELECT <ul>
<li>FROM<br>student<br>WHERE age &gt; 20 ;<br>SELECT * FROM student WHERE age &gt;= 20;</li>
</ul>
</li>
</ul>
<p>— 查询年龄等于20岁<br>SELECT * FROM student WHERE age = 20;</p>
<p>— 查询年龄不等于20岁<br>SELECT <em> FROM student WHERE age != 20;<br>SELECT </em> FROM student WHERE age &lt;&gt; 20;</p>
<p>— 查询年龄大于等于20 小于等于30<br>SELECT <em> FROM student WHERE age &gt;= 20 &amp;&amp;  age &lt;=30;<br>SELECT </em> FROM student WHERE age &gt;= 20 AND  age &lt;=30;<br>SELECT * FROM student WHERE age BETWEEN 20 AND 30; — 闭区间[20, 30]</p>
<p>— 查询年龄22岁，18岁，25岁的信息<br>SELECT <em> FROM student WHERE age = 22 OR age = 18 OR age = 25<br>SELECT </em> FROM student WHERE age IN (22,18,25);</p>
<p>— 查询英语成绩为null<br>SELECT * FROM student WHERE english = NULL; — 错误！null值不能使用 = （!=） 判断</p>
<p>SELECT * FROM student WHERE english IS NULL;</p>
<p>— 查询英语成绩不为null<br>SELECT * FROM student WHERE english  IS NOT NULL;<br>DQL_基础查询_模糊查询<br>LIKE：模糊查询</p>
<p>占位符：<br>_：单个任意字符<br>%：多个任意字符<br>— 查询姓马的有哪些？ like<br>SELECT </p>
<ul>
<li>FROM<br>student<br>WHERE NAME LIKE ‘马%’ ;</li>
</ul>
<p>— 查询姓名第二个字是化的人<br>SELECT * FROM student WHERE NAME LIKE “_化%”;</p>
<p>— 查询姓名是3个字的人<br>SELECT * FROM student WHERE NAME LIKE ‘___’;</p>
<p>— 查询姓名中包含德的人<br>SELECT * FROM student WHERE NAME LIKE ‘%德%’;</p>
<ul>
<li><p>DQL_基础查询</p>
<ul>
<li><ol>
<li><p>多个字段的查询</p>
<ul>
<li>select 字段名1，字段名2… from 表名；</li>
<li>注意：如果查询所有字段，则可以使用*来替代字段列表。</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>去除重复：</p>
<ul>
<li>distinct</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>计算列</p>
<ul>
<li>一般可以使用四则运算计算一些列的值（一般只会进行数值型的计算）。</li>
<li>ifnull(表达式1,表达式2)：null参与的运算，计算结果都为null。</li>
<li>表达式1：哪个字段需要判断是否为null</li>
<li>如果该字段为null后的替换值。</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>起别名：</p>
<ul>
<li>as：as可以省略。</li>
</ul>
</li>
</ol>
</li>
<li><p>CREATE TABLE student (<br>id INT,<br>— 编号<br>NAME VARCHAR (20),<br>— 姓名<br>age INT,<br>— 年龄<br>sex VARCHAR (5),<br>— 性别<br>address VARCHAR (100),<br>— 地址<br>math INT,<br>— 数学<br>english INT— 英语<br>) ;</p>
</li>
</ul>
</li>
</ul>
<p>INSERT INTO student(id,NAME,age,sex,address,math,english) VALUES<br>(1,’马云’,55,’男’,’杭州’,66,78),<br>(2,’马化腾’,45,’女’,’深圳’,98,87),<br>(3,’马景涛’,55,’男’,’香港’,56,77),<br>(4,’柳岩’,20,’女’,’湖南’,76,65),<br>(5,’柳青’,20,’男’,’湖南’,86,NULL),<br>(6,’刘德华’,57,’男’,’香港’,99,99),<br>(7,’马德’,22,’女’,’香港’,99,99),<br>(8,’德玛西亚’,18,’男’,’南京’,56,65);</p>
<p>SELECT * FROM student;</p>
<ul>
<li><p>DQL_条件查询</p>
<ul>
<li><ol>
<li>where子句后跟条件</li>
</ol>
</li>
<li><ol>
<li><p>运算符</p>
<ul>
<li><blockquote>
<p>、&lt; 、&lt;= 、&gt;= 、= 、&lt;&gt;</p>
</blockquote>
</li>
<li>BETWEEN…AND  </li>
<li>IN( 集合) </li>
<li>LIKE：模糊查询</li>
<li>占位符：</li>
<li>_：单个任意字符</li>
<li>%：多个任意字符</li>
<li>IS NULL  </li>
<li>and  或 &amp;&amp;</li>
<li>or  或 || </li>
<li>not  或 !</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
<li><p>DQL_排序查询</p>
<ul>
<li><ol>
<li><p>排序查询</p>
<ul>
<li>语法：order by 子句</li>
<li>order by 排序字段1 排序方式1 ，  排序字段2 排序方式2…</li>
<li><p>排序方式：</p>
<ul>
<li>ASC：升序（默认）。</li>
<li>DESC：降序。</li>
</ul>
</li>
<li><p>注意：</p>
<ul>
<li>如果有多个排序条件，则当前边的条件值一样时，才会判断第二条件。</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>聚合函数：将一列数据作为一个整体，进行纵向的计算</p>
<ul>
<li><p>方法</p>
<ul>
<li>count：计算个数</li>
<li><p>一般选择非空的列：主键</p>
<ul>
<li>count(*)</li>
<li>max：计算最大值</li>
<li>min：计算最小值</li>
<li>sum：计算和</li>
<li>avg：计算平均值</li>
</ul>
</li>
</ul>
</li>
<li><p>注意</p>
<ul>
<li>聚合函数的计算，排除null值。</li>
<li><p>解决方案</p>
<ul>
<li>1、选择不包含非空的列进行计算；</li>
<li>2、IFNULL函数。</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
<li><p>DQL_分组查询</p>
<ul>
<li><ol>
<li><p>分组查询：</p>
<ul>
<li><p>语法</p>
<ul>
<li>group by 分组字段；</li>
</ul>
</li>
<li><p>注意</p>
<ul>
<li>分组之后查询的字段：分组字段、聚合函数</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
<li><p>where 和 having 的区别？</p>
<ul>
<li>where 在分组之前进行限定，如果不满足条件，则不参与分组。having在分组之后进行限定，如果不满足结果，则不会被查询出来</li>
<li>where 后不可以跟聚合函数，having可以进行聚合函数的判断。</li>
</ul>
</li>
<li><p>例子</p>
<ul>
<li><p>— 按照性别分组。分别查询男、女同学的平均分</p>
<ul>
<li>SELECT sex , AVG(math) FROM student GROUP BY sex;</li>
</ul>
</li>
<li><p>— 按照性别分组。分别查询男、女同学的平均分,人数</p>
<ul>
<li>SELECT sex , AVG(math), COUNT(id) FROM student GROUP BY sex;</li>
</ul>
</li>
<li><p>— 按照性别分组。分别查询男、女同学的平均分,人数 要求：分数低于70分的人，不参与分组</p>
<ul>
<li>SELECT sex , AVG(math), COUNT(id) FROM student WHERE math &gt; 70 GROUP BY sex;</li>
</ul>
</li>
<li><p>— 按照性别分组。分别查询男、女同学的平均分,人数 要求：分数低于70分的人，不参与分组,分组之后。人数要大于2个人</p>
<ul>
<li>SELECT sex , AVG(math), COUNT(id) FROM student WHERE math &gt; 70 GROUP BY sex HAVING COUNT(id) &gt; 2;</li>
<li>SELECT sex , AVG(math), COUNT(id) 人数 FROM student WHERE math &gt; 70 GROUP BY sex HAVING 人数 &gt; 2</li>
</ul>
</li>
</ul>
</li>
<li><p>DQL_分页查询</p>
<ul>
<li><ol>
<li><p>分页查询</p>
<ul>
<li><p>语法</p>
<ul>
<li>limit开始的索引,每页查询的条数;</li>
</ul>
</li>
<li><p>公式</p>
<ul>
<li>开始的索引 = （当前的页码 - 1） * 每页显示的条数</li>
<li><p>每页显示3条记录 </p>
<ul>
<li>SELECT * FROM student LIMIT 0,3; — 第1页：从0开始查，查3条记录</li>
<li>SELECT * FROM student LIMIT 3,3; — 第2页：从3开始查，查3条记录</li>
<li>SELECT * FROM student LIMIT 6,3; — 第3页：</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
<h3 id="08-表的约束"><a href="#08-表的约束" class="headerlink" title="08 表的约束"></a>08 表的约束</h3><ul>
<li><p>约束_概述</p>
<ul>
<li>概念：对表中的数据进行限定，保证数据的正确性、有效性和完整性。    </li>
<li><p>分类：</p>
<ul>
<li>1.主键约束：primary key</li>
<li>2.非空约束：not null</li>
<li>3.唯一约束：unique</li>
<li>4.外键约束：foreign key</li>
</ul>
</li>
</ul>
</li>
<li><p>约束_非空约束</p>
<ul>
<li><p>非空约束：not null，值不能为nul</p>
<ul>
<li><ol>
<li><p>创建表时，添加约束</p>
<ul>
<li>CREATE TABLE stu(<br>id INT,<br>NAME VARCHAR(20) NOT NULL — name为非空<br>);</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li>创建表后，再添加非空约束：ALTER TABLE stu MODIFY NAME VARCHAR(20) NOT NULL;</li>
</ol>
</li>
<li><ol>
<li>删除name的非空约束：ALTER TABLE stu MODIFY NAME VARCHAR(20);</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><p>约束_唯一约束</p>
<ul>
<li><p>唯一约束：unique，值不能重复。</p>
<ul>
<li><ol>
<li><p>创建表时，添加唯一约束</p>
<ul>
<li>CREATE TABLE stu(</li>
<li>id INT,</li>
<li>phone_number VARCHAR(20) UNIQUE — 添加了唯一约束</li>
<li>);</li>
<li><ul>
<li>注意mysql中，唯一约束限定的列的值可以有多个null。</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li>删除唯一约束：ALTER TABLE stu DROP INDEX phone_number;</li>
</ol>
</li>
<li><ol>
<li>在创建表后，添加唯一约束：ALTER TABLE stu MODIFY phone_number VARCHAR(20) UNIQUE;</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><p>约束_主键约束</p>
<ul>
<li><p>主键约束：primary key</p>
<ul>
<li><ol>
<li><p>注意：</p>
<ul>
<li><ol>
<li>含义：非空且唯一</li>
</ol>
</li>
<li><ol>
<li>一张表只能有一个字段为主键</li>
</ol>
</li>
<li><ol>
<li>主键就是表中记录的唯一标识</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>在创建表时，添加主键约束</p>
<ul>
<li>create table stu(<br>id int primary key,— 给id添加主键约束<br>name varchar(20)<br>);</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>删除主键</p>
<ul>
<li>ALTER TABLE stu DROP PRIMARY KEY;</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>创建完表后，添加主键</p>
<ul>
<li>ALTER TABLE stu MODIFY id INT PRIMARY KEY;</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><p>约束_主键约束_自动增长</p>
<ul>
<li><ol>
<li><p>自动增长：</p>
<ul>
<li><ol>
<li>概念：如果某一列是数值类型的，使用 auto_increment 可以来完成值得自动增长</li>
</ol>
</li>
<li><ol>
<li><p>在创建表时，添加主键约束，并且完成主键自增长</p>
<ul>
<li>create table stu(</li>
<li>id int primary key auto_increment,— 给id添加主键约束</li>
<li>name varchar(20)</li>
<li>);</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li>删除自动增长：ALTER TABLE stu MODIFY id INT;</li>
</ol>
</li>
<li><ol>
<li>添加自动增长：ALTER TABLE stu MODIFY id INT AUTO_INCREMENT;</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
<li><p>约束_外键约束</p>
<ul>
<li><p>外键约束——缺陷举例</p>
<ul>
<li>CREATE TABLE emp ( — 创建employe表<br>id INT PRIMARY KEY AUTO_INCREMENT,<br>NAME VARCHAR(30),<br>age INT,<br>dep_name VARCHAR(30), — 部门名称<br>dep_location VARCHAR(30) — 部门地址<br>);</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>— 添加数据<br>INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES (‘张三’, 20, ‘研发部’, ‘广州’);<br>INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES (‘李四’, 21, ‘研发部’, ‘广州’);<br>INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES (‘王五’, 20, ‘研发部’, ‘广州’);<br>INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES (‘老王’, 20, ‘销售部’, ‘深圳’);<br>INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES (‘大王’, 22, ‘销售部’, ‘深圳’);<br>INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES (‘小王’, 18, ‘销售部’, ‘深圳’);</p>
<pre><code>    - 解决方案：分成 2 张表

        - -- 创建部门表(id,dep_name,dep_location)
</code></pre><p>— 一方，主表<br>CREATE TABLE department(<br>    id INT PRIMARY KEY AUTO_INCREMENT,<br>    dep_name VARCHAR(20),<br>    dep_location VARCHAR(20)<br>);</p>
<p>— 创建员工表(id,name,age,dep_id)<br>— 多方，从表<br>CREATE TABLE employee(<br>    id INT PRIMARY KEY AUTO_INCREMENT,<br>    NAME VARCHAR(20),<br>    age INT,<br>    dep_id INT — 外键对应主表的主键<br>);</p>
<p>— 添加 2 个部门<br>INSERT INTO department VALUES(NULL, ‘研发部’,’广州’),(NULL, ‘销售部’, ‘深圳’);<br>SELECT * FROM department;</p>
<p>— 添加员工,dep_id 表示员工所在的部门<br>INSERT INTO employee (NAME, age, dep_id) VALUES (‘张三’, 20, 1);<br>INSERT INTO employee (NAME, age, dep_id) VALUES (‘李四’, 21, 1);<br>INSERT INTO employee (NAME, age, dep_id) VALUES (‘王五’, 20, 1);<br>INSERT INTO employee (NAME, age, dep_id) VALUES (‘老王’, 20, 2);<br>INSERT INTO employee (NAME, age, dep_id) VALUES (‘大王’, 22, 2);<br>INSERT INTO employee (NAME, age, dep_id) VALUES (‘小王’, 18, 2);</p>
<p>SELECT <em> FROM employee;<br>SELECT </em> FROM department;</p>
<ul>
<li><p>外键约束 相关概念</p>
<ul>
<li><ul>
<li><p>外键约束：foreign key，让表与表产生关系，从而保证数据的正确性。</p>
<ul>
<li><ol>
<li><p>在创建表时，可以添加外键</p>
<ul>
<li><ul>
<li><p>语法：</p>
<ul>
<li>create table 表名(<br>….<br>外键列<br>constraint 外键名称 foreign key (外键列名称) references 主表名称(主表列名称)<br>);</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>删除外键</p>
<ul>
<li>ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>创建表之后，添加外键</p>
<ul>
<li><p>ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称); // 主键列、唯一约束列</p>
<ul>
<li>CREATE TABLE employee(<br>id INT PRIMARY KEY AUTO_INCREMENT,<br>NAME VARCHAR(20),<br>age INT,<br>dep_id INT, — 外键对应主表的主键<br>CONSTRAINT emp_dept_fk FOREIGN KEY (dep_id) REFERENCES department(id) — 外键约束<br>);</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>级联操作</p>
<ul>
<li><ol>
<li><p>添加级联操作</p>
<ul>
<li>语法：ALTER TABLE 表名 ADD CONSTRAINT 外键名称 </li>
<li>FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称) ON UPDATE CASCADE ON DELETE CASCADE  ;</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>分类：</p>
<ul>
<li><ol>
<li>级联更新：ON UPDATE CASCADE </li>
</ol>
</li>
<li><ol>
<li>级联删除：ON DELETE CASCADE </li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="09-多表操作"><a href="#09-多表操作" class="headerlink" title="09 多表操作"></a>09 多表操作</h3><ul>
<li><p>数据库的设计——1. 多表之间的关系</p>
<ul>
<li><ol>
<li><p>分类：</p>
<ul>
<li><ol>
<li><p>一对一(了解)：</p>
<ul>
<li><ul>
<li>如：人和身份证</li>
</ul>
</li>
<li><ul>
<li>分析：一个人只有一个身份证，一个身份证只能对应一个人。</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>一对多(多对一)：</p>
<ul>
<li><ul>
<li>如：部门和员工</li>
</ul>
</li>
<li><ul>
<li>分析：一个部门有多个员工，一个员工只能对应一个部门。</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>多对多：</p>
<ul>
<li><ul>
<li>如：学生和课程</li>
</ul>
</li>
<li><ul>
<li>分析：一个学生可以选择很多门课程，一个课程也可以被很多学生选择。</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>实现关系：</p>
<ul>
<li><ol>
<li><p>一对多(多对一)：</p>
<ul>
<li><ul>
<li>如：部门和员工</li>
</ul>
</li>
<li><ul>
<li>实现方式：在多的一方建立外键，指向一的一方的主键。</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><p>多表关系_多对多关系实现</p>
<ul>
<li><ol>
<li><p>实现关系：</p>
<ul>
<li><ol>
<li><p>一对多(多对一)：</p>
<ul>
<li><ul>
<li>如：部门和员工</li>
</ul>
</li>
<li><ul>
<li>实现方式：在多的一方建立外键，指向一的一方的主键。</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>多对多：</p>
<ul>
<li><ul>
<li>如：学生和课程</li>
</ul>
</li>
<li><ul>
<li>实现方式：多对多关系实现需要借助第三张中间表。中间表至少包含两个字段，这两个字段作为第三张表的外键，分别指向两张表的主键。</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>一对一(了解)：</p>
<ul>
<li><ul>
<li>如：人和身份证</li>
</ul>
</li>
<li><ul>
<li>实现方式：一对一关系实现，可以在任意一方添加唯一外键指向另一方的主键。</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
<li><p>多表关系_一对一关系实现</p>
<ul>
<li><ol>
<li><p>实现关系：</p>
<ul>
<li><ol>
<li><p>一对多(多对一)：</p>
<ul>
<li><ul>
<li>如：部门和员工</li>
</ul>
</li>
<li><ul>
<li>实现方式：在多的一方建立外键，指向一的一方的主键。</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>多对多：</p>
<ul>
<li><ul>
<li>如：学生和课程</li>
</ul>
</li>
<li><ul>
<li>实现方式：多对多关系实现需要借助第三张中间表。中间表至少包含两个字段，这两个字段作为第三张表的外键，分别指向两张表的主键。</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>一对一(了解)：</p>
<ul>
<li><ul>
<li>如：人和身份证</li>
</ul>
</li>
<li><ul>
<li>实现方式：一对一关系实现，可以在任意一方添加唯一外键指向另一方的主键</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><p>— 创建旅游线路分类表 tab_category<br>— cid 旅游线路分类主键，自动增长<br>— cname 旅游线路分类名称非空，唯一，字符串 100<br>CREATE TABLE tab_category (<br>cid INT PRIMARY KEY AUTO_INCREMENT,<br>cname VARCHAR (100) NOT NULL UNIQUE<br>) ;</p>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>— 创建旅游线路表 tab_route<br>/<em><br>rid 旅游线路主键，自动增长<br>rname 旅游线路名称非空，唯一，字符串 100<br>price 价格<br>rdate 上架时间，日期类型<br>cid 外键，所属分类
</em>/<br>CREATE TABLE tab_route (<br>  rid INT PRIMARY KEY AUTO_INCREMENT,<br>  rname VARCHAR (100) NOT NULL UNIQUE,<br>  price DOUBLE,<br>  rdate DATE,<br>  cid INT,<br>  FOREIGN KEY (cid) REFERENCES tab_category (cid)<br>) ;</p>
<p>/<em>创建用户表 tab_user<br>uid 用户主键，自增长<br>username 用户名长度 100，唯一，非空<br>password 密码长度 30，非空<br>name 真实姓名长度 100<br>birthday 生日<br>sex 性别，定长字符串 1<br>telephone 手机号，字符串 11<br>email 邮箱，字符串长度 100
</em>/<br>CREATE TABLE tab_user (<br>  uid INT PRIMARY KEY AUTO_INCREMENT,<br>  username VARCHAR (100) UNIQUE NOT NULL,<br>  PASSWORD VARCHAR (30) NOT NULL,<br>  NAME VARCHAR (100),<br>  birthday DATE,<br>  sex CHAR(1) DEFAULT ‘男’,<br>  telephone VARCHAR (11),<br>  email VARCHAR (100)<br>) ;</p>
<p>/<em><br>创建收藏表 tab_favorite<br>rid 旅游线路 id，外键<br>date 收藏时间<br>uid 用户 id，外键<br>rid 和 uid 不能重复，设置复合主键，同一个用户不能收藏同一个线路两次
</em>/<br>CREATE TABLE tab_favorite (<br>  rid INT, — 线路id<br>  DATE DATETIME,<br>  uid INT,<br>  — 用户id<br>  — 创建复合主键<br>  PRIMARY KEY (rid, uid),<br>  — 联合主键<br>  FOREIGN KEY (rid) REFERENCES tab_route (rid),<br>  FOREIGN KEY (uid) REFERENCES tab_user (uid)</p>
<h3 id="10-三大范式"><a href="#10-三大范式" class="headerlink" title="10 三大范式"></a>10 三大范式</h3><ul>
<li><ol>
<li><p>数据库设计的范式</p>
<ul>
<li><ul>
<li><p>概念：设计数据库时，需要遵循的一些规范。要遵循后边的范式要求，必须先遵循前边的所有范式要求。</p>
<ul>
<li>设计关系数据库时，遵从不同的规范要求，设计出合理的关系型数据库，这些不同的规范要求被称为不同的范式，各种范式呈递次规范，越高的范式数据库冗余越小。</li>
<li><p>目前关系数据库有六种范式</p>
<ul>
<li>第一范式（1NF）</li>
<li>第二范式（2NF）</li>
<li>第三范式（3NF）</li>
<li>巴斯-科德范式（BCNF）</li>
<li>第四范式(4NF）</li>
<li>第五范式（5NF，又称完美范式）</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>分类：</p>
<ul>
<li><ol>
<li>第一范式（1NF）：每一列都是不可分割的原子数据项。</li>
</ol>
</li>
<li><ol>
<li>第二范式（2NF）：在1NF的基础上，非码属性必须完全依赖于码（在1NF基础上消除非主属性对主码的部分函数依赖）。</li>
</ol>
</li>
<li><ol>
<li>第三范式（3NF）：在2NF基础上，任何非主属性不依赖于其它非主属性（在2NF基础上消除传递依赖）。</li>
</ol>
</li>
<li><ul>
<li><p>几个概念：</p>
<ul>
<li><ol>
<li><p>函数依赖：A—&gt;B,如果通过A属性(属性组)的值，可以确定唯一B属性的值，则称B依赖于A。</p>
<ul>
<li>例如：学号—&gt;姓名。  （学号，课程名称） —&gt; 分数</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>完全函数依赖：A—&gt;B， 如果A是一个属性组，则B属性值的确定需要依赖于A属性组中所有的属性值。</p>
<ul>
<li>例如：（学号，课程名称） —&gt; 分数</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>部分函数依赖：A—&gt;B， 如果A是一个属性组，则B属性值的确定只需要依赖于A属性组中某一些值即可。</p>
<ul>
<li>例如：（学号，课程名称） —&gt; 姓名</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>传递函数依赖：A—&gt;B, B—&gt;C。如果通过A属性(属性组)的值，可以确定唯一B属性的值，在通过B属性（属性组）的值可以确定唯一C属性的值，则称C传递函数依赖于A。</p>
<ul>
<li>例如：学号—&gt;系名，系名—&gt;系主任</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>码：如果在一张表中，一个属性或属性组，被其他所有属性所完全依赖，则称这个属性(属性组)为该表的码。</p>
<ul>
<li>例如：该表中码为：（学号，课程名称）</li>
<li><ul>
<li>主属性：码属性组中的所有属性</li>
</ul>
</li>
<li><ul>
<li>非主属性：除过码属性组的属性</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
<h3 id="11-数据库的备份和还原"><a href="#11-数据库的备份和还原" class="headerlink" title="11 数据库的备份和还原"></a>11 数据库的备份和还原</h3><ul>
<li><ol>
<li><p>命令行：</p>
<ul>
<li><ul>
<li><p>语法：</p>
<ul>
<li><ul>
<li>备份：mysqldump -u用户名 -p密码 数据库名称 &gt; 保存的路径</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>还原：</p>
<ul>
<li><ol>
<li>登录数据库</li>
</ol>
</li>
<li><ol>
<li>创建数据库</li>
</ol>
</li>
<li><ol>
<li>使用数据库</li>
</ol>
</li>
<li><ol>
<li>执行文件。source 文件路径</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li>图形化工具</li>
</ol>
</li>
</ul>
<h3 id="12-多表查询"><a href="#12-多表查询" class="headerlink" title="12 多表查询"></a>12 多表查询</h3><ul>
<li><p>多表查询_概述</p>
<ul>
<li><ul>
<li><p>查询语法：</p>
<ul>
<li>select<br>列名列表<br>from<br>表名列表<br>where….</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>准备sql</p>
<ul>
<li><h1 id="创建部门表"><a href="#创建部门表" class="headerlink" title="创建部门表"></a>创建部门表</h1><ul>
<li>CREATE TABLE dept(<br>id INT PRIMARY KEY AUTO_INCREMENT,<br>NAME VARCHAR(20)<br>);<br>INSERT INTO dept (NAME) VALUES (‘开发部’),(‘市场部’),(‘财务部’);</li>
</ul>
</li>
<li><h1 id="创建员工表"><a href="#创建员工表" class="headerlink" title="创建员工表"></a>创建员工表</h1><ul>
<li>CREATE TABLE emp (<br>id INT PRIMARY KEY AUTO_INCREMENT,<br>NAME VARCHAR(10),<br>gender CHAR(1), — 性别<br>salary DOUBLE, — 工资<br>join_date DATE, — 入职日期<br>dept_id INT,<br>FOREIGN KEY (dept_id) REFERENCES dept(id) — 外键，关联部门表(部门表的主键)<br>);</li>
</ul>
</li>
<li><h1 id="插入数据"><a href="#插入数据" class="headerlink" title="插入数据"></a>插入数据</h1><ul>
<li>INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES(‘孙悟空’,’男’,7200,’2013-02-24’,1);<br>INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES(‘猪八戒’,’男’,3600,’2010-12-02’,2);<br>INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES(‘唐僧’,’男’,9000,’2008-08-08’,2);<br>INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES(‘白骨精’,’女’,5000,’2015-10-07’,3);<br>INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES(‘蜘蛛精’,’女’,4500,’2011-03-14’,1);</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>笛卡尔积：</p>
<ul>
<li><ul>
<li>有两个集合A,B，取这两个集合的所有组成情况。</li>
</ul>
</li>
<li><ul>
<li>要完成多表查询，需要消除无用的数据。</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>多表查询的分类：</p>
<ul>
<li><ol>
<li><p>内连接查询</p>
<ul>
<li><ol>
<li><p>隐式内连接：使用where条件消除无用数据。</p>
<ul>
<li><ul>
<li>例子：</li>
</ul>
<ul>
<li><p>— 查询所有员工信息和对应的部门信息</p>
<ul>
<li>SELECT * FROM emp, dept WHERE emp.<code>dept_id</code> = dept.<code>id</code>;</li>
</ul>
</li>
<li><p>— 查询员工表的名称，性别。部门表的名称</p>
<ul>
<li>SELECT emp.name, emp.gender, dept.name FROM emp, dept WHERE emp.<code>dept_id</code> = dept.<code>id</code>;</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>显式内连接：</p>
<ul>
<li><ul>
<li>语法： select 字段列表 from 表名1 [inner] join 表名2 on 条件</li>
</ul>
<ul>
<li><ul>
<li><p>例如：</p>
<ul>
<li><ul>
<li>SELECT * FROM emp INNER JOIN dept ON emp.<code>dept_id</code> = dept.<code>id</code>;    </li>
</ul>
</li>
<li><ul>
<li>SELECT * FROM emp JOIN dept ON emp.<code>dept_id</code> = dept.<code>id</code>;    </li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>内连接查询（注意事项）：</p>
<ul>
<li><ol>
<li>从哪些表中查询数据</li>
</ol>
</li>
<li><ol>
<li>条件是什么</li>
</ol>
</li>
<li><ol>
<li>查询哪些字段</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>外连接查询</p>
<ul>
<li><ol>
<li><p>左外连接：</p>
<ul>
<li><ul>
<li>语法：select 字段列表 from 表1 left [outer] join 表2 on 条件；</li>
</ul>
</li>
<li><ul>
<li>查询的是左表所有数据以及其交集部分。</li>
</ul>
</li>
<li><ul>
<li>例子：</li>
</ul>
<ul>
<li><p>— 查询所有员工信息，如果员工有部门，则查询部门名称，没有部门，则不显示部门名称</p>
<ul>
<li>SELECT t1.*,t2.<code>name</code> FROM emp t1 LEFT JOIN dept t2 ON t1.<code>dept_id</code> = t2.<code>id</code>;</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>右外连接：</p>
<ul>
<li><ul>
<li>语法：select 字段列表 from 表1 right [outer] join 表2 on 条件；</li>
</ul>
</li>
<li><ul>
<li>查询的是右表所有数据以及其交集部分。</li>
</ul>
</li>
<li><ul>
<li>例子：</li>
</ul>
<ul>
<li>SELECT * FROM dept t2 RIGHT JOIN emp t1 ON t1.<code>dept_id</code> = t2.<code>id</code>;</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>子查询</p>
<ul>
<li><ul>
<li>概念：查询中嵌套查询，称嵌套查询为子查询。</li>
</ul>
</li>
<li><p>— 查询工资最高的员工信息</p>
<ul>
<li>SELECT MAX(salary) FROM emp;</li>
</ul>
</li>
<li><p>— 2 查询员工信息，并且工资等于9000的</p>
<ul>
<li>SELECT * FROM emp WHERE emp.<code>salary</code> = 9000;</li>
</ul>
</li>
<li><p>— 一条sql就完成这个操作。子查询</p>
<ul>
<li>SELECT * FROM emp WHERE emp.<code>salary</code> = (SELECT MAX(salary) FROM emp);</li>
</ul>
</li>
<li><ul>
<li><p>子查询不同情况</p>
<ul>
<li><ol>
<li><p>子查询的结果是单行单列的：</p>
<ul>
<li><ul>
<li>子查询可以作为条件，使用运算符去判断。 运算符： &gt; &gt;= &lt; &lt;= =</li>
</ul>
</li>
<li><p>— 查询员工工资小于平均工资的人</p>
<ul>
<li>SELECT * FROM emp WHERE emp.salary &lt; (SELECT AVG(salary) FROM emp);</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><p>2.子查询的结果是多行单列的：</p>
<ul>
<li><ul>
<li>子查询可以作为条件，使用运算符in来判断</li>
</ul>
</li>
<li><p>— 查询’财务部’和’市场部’所有的员工信息</p>
<ul>
<li>SELECT id FROM dept WHERE NAME = ‘财务部’ OR NAME = ‘市场部’;</li>
<li>SELECT * FROM emp WHERE dept_id = 3 OR dept_id = 2;</li>
</ul>
</li>
<li><p>— 子查询</p>
<ul>
<li>SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE NAME = ‘财务部’ OR NAME = ‘市场部’);</li>
</ul>
</li>
</ul>
</li>
<li><ol>
<li><p>子查询的结果是多行多列的：</p>
<ul>
<li><ul>
<li>子查询可以作为一张虚拟表参与查询</li>
</ul>
</li>
<li><p>— 查询员工入职日期是2011-11-11日之后的员工信息和部门信息</p>
<ul>
<li><p>— 子查询</p>
<ul>
<li>SELECT <em> FROM dept t1 ,(SELECT </em> FROM emp WHERE emp.<code>join_date</code> &gt; ‘2011-11-11’) t2 WHERE t1.id = t2.dept_id;</li>
</ul>
</li>
<li><p>— 普通内连接</p>
<ul>
<li>SELECT * FROM emp t1,dept t2 WHERE t1.<code>dept_id</code> = t2.<code>id</code> AND t1.<code>join_date</code> &gt;  ‘2011-11-11’;</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="14-多表查询练习"><a href="#14-多表查询练习" class="headerlink" title="14 多表查询练习"></a>14 多表查询练习</h3><ul>
<li><p>创建 数据库db3、创建 4个 数据表</p>
<ul>
<li><p>代码</p>
<p>— 部门表<br>CREATE TABLE dept (<br>  id INT PRIMARY KEY PRIMARY KEY, — 部门id<br>  dname VARCHAR(50), — 部门名称<br>  loc VARCHAR(50) — 部门所在地<br>);</p>
<p>— 添加4个部门<br>INSERT INTO dept(id,dname,loc) VALUES<br>(10,’教研部’,’北京’),<br>(20,’学工部’,’上海’),<br>(30,’销售部’,’广州’),<br>(40,’财务部’,’深圳’);</p>
</li>
</ul>
</li>
</ul>
<pre><code>  -- 职务表，职务名称，职务描述
  CREATE TABLE job (
    id INT PRIMARY KEY,
    jname VARCHAR(20),
    description VARCHAR(50)
  );

  -- 添加4个职务
  INSERT INTO job (id, jname, description) VALUES
  (1, &#39;董事长&#39;, &#39;管理整个公司，接单&#39;),
  (2, &#39;经理&#39;, &#39;管理部门员工&#39;),
  (3, &#39;销售员&#39;, &#39;向客人推销产品&#39;),
  (4, &#39;文员&#39;, &#39;使用办公软件&#39;);



  -- 员工表
  CREATE TABLE emp (
    id INT PRIMARY KEY, -- 员工id
    ename VARCHAR(50), -- 员工姓名
    job_id INT, -- 职务id
    mgr INT , -- 上级领导
    joindate DATE, -- 入职日期
    salary DECIMAL(7,2), -- 工资
    bonus DECIMAL(7,2), -- 奖金
    dept_id INT, -- 所在部门编号
    CONSTRAINT emp_jobid_ref_job_id_fk FOREIGN KEY (job_id) REFERENCES job (id),
    CONSTRAINT emp_deptid_ref_dept_id_fk FOREIGN KEY (dept_id) REFERENCES dept (id)
  );

  -- 添加员工
  INSERT INTO emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) VALUES 
  (1001,&#39;孙悟空&#39;,4,1004,&#39;2000-12-17&#39;,&#39;8000.00&#39;,NULL,20),
  (1002,&#39;卢俊义&#39;,3,1006,&#39;2001-02-20&#39;,&#39;16000.00&#39;,&#39;3000.00&#39;,30),
  (1003,&#39;林冲&#39;,3,1006,&#39;2001-02-22&#39;,&#39;12500.00&#39;,&#39;5000.00&#39;,30),
  (1004,&#39;唐僧&#39;,2,1009,&#39;2001-04-02&#39;,&#39;29750.00&#39;,NULL,20),
  (1005,&#39;李逵&#39;,4,1006,&#39;2001-09-28&#39;,&#39;12500.00&#39;,&#39;14000.00&#39;,30),
  (1006,&#39;宋江&#39;,2,1009,&#39;2001-05-01&#39;,&#39;28500.00&#39;,NULL,30),
  (1007,&#39;刘备&#39;,2,1009,&#39;2001-09-01&#39;,&#39;24500.00&#39;,NULL,10),
  (1008,&#39;猪八戒&#39;,4,1004,&#39;2007-04-19&#39;,&#39;30000.00&#39;,NULL,20),
  (1009,&#39;罗贯中&#39;,1,NULL,&#39;2001-11-17&#39;,&#39;50000.00&#39;,NULL,10),
  (1010,&#39;吴用&#39;,3,1006,&#39;2001-09-08&#39;,&#39;15000.00&#39;,&#39;0.00&#39;,30),
  (1011,&#39;沙僧&#39;,4,1004,&#39;2007-05-23&#39;,&#39;11000.00&#39;,NULL,20),
  (1012,&#39;李逵&#39;,4,1006,&#39;2001-12-03&#39;,&#39;9500.00&#39;,NULL,30),
  (1013,&#39;小白龙&#39;,4,1004,&#39;2001-12-03&#39;,&#39;30000.00&#39;,NULL,20),
  (1014,&#39;关羽&#39;,4,1007,&#39;2002-01-23&#39;,&#39;13000.00&#39;,NULL,10);



  -- 工资等级表
  CREATE TABLE salarygrade (
    grade INT PRIMARY KEY,  -- 级别
    losalary INT, -- 最低工资
    hisalary INT -- 最高工资
  );

  -- 添加5个工资等级
  INSERT INTO salarygrade(grade,losalary,hisalary) VALUES 
  (1,7000,12000),
  (2,12010,14000),
  (3,14010,20000),
  (4,20010,30000),
  (5,30010,99990);

- 需求：

    - -- 1.查询所有员工信息。查询员工编号，员工姓名，工资，职务名称，职务描述
    - -- 2.查询员工编号，员工姓名，工资，职务名称，职务描述，部门名称，部门位置
    - -- 3.查询员工姓名，工资，工资等级
    - -- 4.查询员工姓名，工资，职务名称，职务描述，部门名称，部门位置，工资等级
    - -- 5.查询出部门编号、部门名称、部门位置、部门人数
    - -- 6.查询所有员工的姓名及其直接上级的姓名,没有领导的员工也需要查
    - -- 7.查询所有员工信息：查询员工编号，员工姓名，工资，职务名称，职务描述。

- 分析：

    - 员工编号，员工姓名，工资，需要查询emp表  职务名称，职务描述 需要查询job表
</code></pre><p>查询条件 emp.job_id = job.id<br>SELECT<br>    t1.<code>id</code>, — 员工编号<br>    t1.<code>ename</code>, — 员工姓名<br>    t1.<code>salary</code>,— 工资<br>    t2.<code>jname</code>, — 职务名称<br>    t2.<code>description</code> — 职务描述<br>FROM<br>    emp t1, job t2<br>WHERE<br>    t1.<code>job_id</code> = t2.<code>id</code>;</p>
<pre><code>- 需求2

    - -- 2.查询员工编号、员工姓名、工资、职务名称、职务描述、部门名称、部门位置。

- 分析：

    - 员工编号，员工姓名，工资 emp 职务名称，职务描述 job 部门名称，部门位置 dept
</code></pre><p>条件： emp.job_id = job.id and emp.dept_id = dept.id<br>SELECT<br>    t1.<code>id</code>, — 员工编号<br>    t1.<code>ename</code>, — 员工姓名<br>    t1.<code>salary</code>,— 工资<br>    t2.<code>jname</code>, — 职务名称<br>    t2.<code>description</code>, — 职务描述<br>    t3.<code>dname</code>, — 部门名称<br>    t3.<code>loc</code> — 部门位置<br>FROM<br>    emp t1, job t2,dept t3<br>WHERE<br>    t1.<code>job_id</code> = t2.<code>id</code> AND t1.<code>dept_id</code> = t3.<code>id</code>;</p>
<pre><code>- 需求3
- -- 3.查询员工姓名、工资、工资等级。
- 分析：

    - 员工姓名，工资 emp  工资等级 salarygrade
</code></pre><p>条件 emp.salary &gt;= salarygrade.losalary and emp.salary &lt;= salarygrade.hisalary / emp.salary BETWEEN salarygrade.losalary and salarygrade.hisalary<br>SELECT<br>    t1.ename ,<br>    t1.<code>salary</code>,<br>    t2.*<br>FROM emp t1, salarygrade t2<br>WHERE t1.<code>salary</code> BETWEEN t2.<code>losalary</code> AND t2.<code>hisalary</code>;</p>
<pre><code>- 需求4
- -- 4.查询员工姓名、工资、职务名称、职务描述、部门名称、部门位置、工资等级。
- 分析：

    - 员工姓名，工资 emp ， 职务名称，职务描述 job 部门名称，部门位置，dept 工资等级 salarygrade
</code></pre><p>条件： emp.job_id = job.id and emp.dept_id = dept.id and emp.salary BETWEEN salarygrade.losalary and salarygrade.hisalary<br>SELECT<br>    t1.<code>ename</code>,<br>    t1.<code>salary</code>,<br>    t2.<code>jname</code>,<br>    t2.<code>description</code>,<br>    t3.<code>dname</code>,<br>    t3.<code>loc</code>,<br>    t4.<code>grade</code><br>FROM<br>    emp t1,job t2,dept t3,salarygrade t4<br>WHERE<br>    t1.<code>job_id</code> = t2.<code>id</code><br>    AND t1.<code>dept_id</code> = t3.<code>id</code><br>    AND t1.<code>salary</code> BETWEEN t4.<code>losalary</code> AND t4.<code>hisalary</code>;</p>
<pre><code>- 需求5
- -- 5.查询出部门编号、部门名称、部门位置、部门人数。
- 分析：
- 部门编号、部门名称、部门位置 dept 表。 部门人数 emp表
- 使用分组查询。按照emp.dept_id完成分组，查询count(id)
- 使用子查询将第2步的查询结果和dept表进行关联查询

    - SELECT 
t1.`id`,
t1.`dname`,
t1.`loc`,
t2.total
</code></pre><p>FROM<br>    dept t1,<br>    (SELECT<br>        dept_id,COUNT(id) total — 别名total<br>    FROM<br>        emp<br>    GROUP BY dept_id) t2<br>WHERE t1.<code>id</code> = t2.dept_id;</p>
<pre><code>- 需求6
- -- 6.查询所有员工的姓名及其直接上级的姓名，没有领导的员工 也需要查询。
- 分析：

    - 姓名 emp， 直接上级的姓名 emp    * emp表的id 和 mgr 是自关联
</code></pre><p>条件 emp.id = emp.mgr<br>查询左表的所有数据，和 交集数据    * 使用左外连接查询<br>SELECT<br>    t1.ename,<br>    t1.mgr,<br>    t2.<code>id</code>,<br>    t2.ename<br>FROM emp t1, emp t2<br>WHERE t1.mgr = t2.<code>id</code>;</p>
<p>SELECT<br>    t1.ename,<br>    t1.mgr,<br>    t2.<code>id</code>,<br>    t2.<code>ename</code><br>FROM emp t1<br>LEFT JOIN emp t2<br>ON t1.<code>mgr</code> = t2.<code>id</code>;</p>
<h3 id="15-事务"><a href="#15-事务" class="headerlink" title="15 事务"></a>15 事务</h3><ul>
<li><ol>
<li><p>事务的基本介绍</p>
<ul>
<li><ol>
<li><p>概念：</p>
<ul>
<li>*如果一个包含多个步骤的业务操作，被事务管理，那么这些操作要么同时成功，要么同时失败。        </li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>操作：</p>
<ul>
<li><ol>
<li>开启事务： start transaction;</li>
</ol>
</li>
<li><ol>
<li>回滚：rollback;</li>
</ol>
</li>
<li><ol>
<li>提交：commit;</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>例子：</p>
<ul>
<li>CREATE TABLE account (<br>id INT PRIMARY KEY AUTO_INCREMENT,<br>NAME VARCHAR(10),<br>balance DOUBLE<br>);<br>— 添加数据<br>INSERT INTO account (NAME, balance) VALUES (‘zhangsan’, 1000), (‘lisi’, 1000);<br>SELECT * FROM account;<br>UPDATE account SET balance = 1000;<br>— 张三给李四转账 500 元<br>— 0. 开启事务<br>START TRANSACTION;<br>— 1. 张三账户 -500<br>UPDATE account SET balance = balance - 500 WHERE NAME = ‘zhangsan’;<br>— 2. 李四账户 +500<br>— 出错了…<br>UPDATE account SET balance = balance + 500 WHERE NAME = ‘lisi’;<br>— 发现执行没有问题，提交事务<br>COMMIT;<br>— 发现出问题了，回滚事务<br>ROLLBACK;</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>MySQL数据库中事务默认自动提交</p>
<ul>
<li><ul>
<li>事务提交的两种方式：</li>
</ul>
<ul>
<li><ul>
<li><p>自动提交：</p>
<ul>
<li><ul>
<li>mysql就是自动提交的</li>
</ul>
</li>
<li><ul>
<li>一条DML(增删改)语句会自动提交一次事务。</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>手动提交：</p>
<ul>
<li><ul>
<li>Oracle 数据库默认是手动提交事务</li>
</ul>
</li>
<li><ul>
<li>需要先开启事务，再提交</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li>修改事务的默认提交方式：</li>
</ul>
<ul>
<li><ul>
<li>查看事务的默认提交方式：SELECT @@autocommit; — 1 代表自动提交  0 代表手动提交</li>
</ul>
</li>
<li><ul>
<li>修改默认提交方式： set @@autocommit = 0;</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>事务的四大特征：</p>
<ul>
<li><ol>
<li>原子性：是不可分割的最小操作单位，要么同时成功，要么同时失败。</li>
</ol>
</li>
<li><ol>
<li>持久性：当事务提交或回滚后，数据库会持久化的保存数据。</li>
</ol>
</li>
<li><ol>
<li>隔离性：多个事务之间。相互独立。</li>
</ol>
</li>
<li><ol>
<li>一致性：事务操作前后，数据总量不变</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>事务的隔离级别</p>
<ul>
<li><ul>
<li>概念：多个事务之间隔离的，相互独立的。但是如果多个事务操作同一批数据，则会引发一些问题，设置不同的隔离级别就可以解决这些问题。</li>
</ul>
</li>
<li><ul>
<li><p>存在问题：</p>
<ul>
<li><ol>
<li>脏读：一个事务，读取到另一个事务中没有提交的数据</li>
</ol>
</li>
<li><ol>
<li>幻读：一个事务操作(DML)数据表中所有记录，另一个事务添加了一条数据，则第一个事务查询不到自己的修改。</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>隔离级别：</p>
<ul>
<li><ol>
<li><p>read uncommitted：读未提交</p>
<ul>
<li><ul>
<li>产生的问题：脏读、不可重复读、幻读</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>read committed：读已提交 （Oracle）</p>
<ul>
<li><ul>
<li>产生的问题：不可重复读、幻读</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>repeatable read：可重复读 （MySQL默认）</p>
<ul>
<li><ul>
<li>产生的问题：幻读</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>serializable：串行化</p>
<ul>
<li><ul>
<li>可以解决所有的问题</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ul>
<li>注意：隔离级别从小到大，安全性越来越高，但是效率越来越低。</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>数据库查询隔离级别：</p>
<ul>
<li><ul>
<li>select @@tx_isolation;</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>数据库设置隔离级别：</p>
<ul>
<li><ul>
<li>set global transaction isolation level 级别字符串;</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li><p>演示：</p>
<ul>
<li>set global transaction isolation level read uncommitted;<br>start transaction;<br>— 转账操作<br>update account set balance = balance - 500 where id = 1;<br>update account set balance = balance + 500 where id = 2;</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
</ul>
<h3 id="16-用户管理和权限管理"><a href="#16-用户管理和权限管理" class="headerlink" title="16 用户管理和权限管理"></a>16 用户管理和权限管理</h3><ul>
<li><ul>
<li><p>SQL分类：</p>
<ul>
<li><ol>
<li>DDL：操作数据库和表</li>
</ol>
</li>
<li><ol>
<li>DML：增删改表中数据</li>
</ol>
</li>
<li><ol>
<li>DQL：查询表中数据</li>
</ol>
</li>
<li><ol>
<li>DCL：管理用户，授权</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><ul>
<li>DBA：数据库管理员</li>
</ul>
</li>
<li><ul>
<li>DCL：管理用户，授权</li>
</ul>
</li>
<li><ol>
<li><p>管理用户</p>
<ul>
<li><ol>
<li><p>添加用户：</p>
<ul>
<li><ul>
<li>语法：CREATE USER ‘用户名’@’主机名’ IDENTIFIED BY ‘密码’;</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>删除用户：</p>
<ul>
<li><ul>
<li>语法：DROP USER ‘用户名’@’主机名’;</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>修改用户密码</p>
<ul>
<li>UPDATE USER SET PASSWORD = PASSWORD(‘新密码’) WHERE USER = ‘用户名’;</li>
<li>UPDATE USER SET PASSWORD = PASSWORD(‘abc’) WHERE USER = ‘lisi’;</li>
<li>SET PASSWORD FOR ‘用户名’@’主机名’ = PASSWORD(‘新密码’);</li>
<li>SET PASSWORD FOR ‘root’@’localhost’ = PASSWORD(‘123’);</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>查询用户：</p>
<ul>
<li>— 1. 切换到mysql数据库</li>
<li>USE myql;</li>
<li>— 2. 查询user表</li>
<li>SELECT * FROM USER;</li>
<li><ul>
<li>通配符： % 表示可以在任意主机使用用户登录数据库</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ul>
<li><p>mysql中忘记了root用户的密码？</p>
<ul>
<li><ol>
<li>cmd — &gt; net stop mysql 停止mysql服务(需要管理员运行该cmd)</li>
</ol>
</li>
<li><ol>
<li>使用无验证方式启动mysql服务： mysqld —skip-grant-tables</li>
</ol>
</li>
<li><ol>
<li>打开新的cmd窗口,直接输入mysql命令，敲回车。就可以登录成功</li>
</ol>
</li>
<li><ol>
<li>use mysql;</li>
</ol>
</li>
<li><ol>
<li>update user set password = password(‘你的新密码’) where user = ‘root’;</li>
</ol>
</li>
<li><ol>
<li>关闭两个窗口</li>
</ol>
</li>
<li><ol>
<li>打开任务管理器，手动结束mysqld.exe 的进程</li>
</ol>
</li>
<li><ol>
<li>启动mysql服务</li>
</ol>
</li>
<li><ol>
<li>使用新密码登录。</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>权限管理：</p>
<ul>
<li><ol>
<li><p>查询权限：</p>
<ul>
<li>SHOW GRANTS FOR ‘用户名’@’主机名’;</li>
<li>SHOW GRANTS FOR ‘lisi’@’%’;</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>授予权限：</p>
<ul>
<li>grant 权限列表 on 数据库名.表名 to ‘用户名’@’主机名’;</li>
<li>— 给张三用户授予所有权限，在任意数据库任意表上</li>
<li>GRANT ALL ON <em>.</em> TO ‘zhangsan’@’localhost’;</li>
</ul>
</li>
</ol>
</li>
<li><ol>
<li><p>撤销权限：</p>
<ul>
<li>— 撤销权限：</li>
<li>revoke 权限列表 on 数据库名.表名 from ‘用户名’@’主机名’;</li>
<li>REVOKE UPDATE ON db3.<code>account</code> FROM ‘lisi’@’%’;</li>
</ul>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
</ul>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://goofyer.gitee.io/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E4%B8%89%E7%AB%A0MySQL/" data-id="cl403sxrc001sf8vuh8kb879j" data-title="" class="article-share-link">Share</a>
      
      
      
    </footer>
  </div>
  
</article>



  
    <article id="post-Java/第十二章 反射" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E4%BA%8C%E7%AB%A0%20%E5%8F%8D%E5%B0%84/" class="article-date">
  <time class="dt-published" datetime="2021-12-19T17:33:15.674Z" itemprop="datePublished">2021-12-20</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h2 id="第十二章-反射"><a href="#第十二章-反射" class="headerlink" title="第十二章 反射"></a>第十二章 反射</h2>
      
    </div>
    <footer class="article-footer">
      <a data-url="https://goofyer.gitee.io/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E4%BA%8C%E7%AB%A0%20%E5%8F%8D%E5%B0%84/" data-id="cl403sxrd001uf8vuc2vvd7p0" data-title="" class="article-share-link">Share</a>
      
      
      
    </footer>
  </div>
  
</article>



  
    <article id="post-Java/第十一章函数式接口" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E4%B8%80%E7%AB%A0%E5%87%BD%E6%95%B0%E5%BC%8F%E6%8E%A5%E5%8F%A3/" class="article-date">
  <time class="dt-published" datetime="2021-12-19T17:33:08.446Z" itemprop="datePublished">2021-12-20</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h2 id="第十一章函数式接口"><a href="#第十一章函数式接口" class="headerlink" title="第十一章函数式接口"></a>第十一章函数式接口</h2><h3 id="01-函数式接口"><a href="#01-函数式接口" class="headerlink" title="01_函数式接口"></a>01_函数式接口</h3><ul>
<li>函数式接口概念：有且仅有一个抽象方法的接口。</li>
<li>Java中的函数式编程体现就是Lambda表达式，所以函数式接口就是可以适用于Lambda使用的接口。</li>
<li>只有确保接口中有且仅有一个抽象方法，Java中的Lambda才能顺利地进行推导。</li>
<li><p>如何检测一个接口是不是函数式接口：</p>
<ul>
<li>@FunctionalInterface</li>
<li>放在接口定义的上方：如果接口是函数式接口，编译通过；如果不是，编译失败。</li>
</ul>
</li>
<li><p>注意事项：</p>
<ul>
<li>我们自己定义函数式接口的时候，@FunctionalInterface是可选的，就算我不写这个注解，只要保证满足函数式接口定义的条件，也照样是函数式接口。但是，建议加上该注解。</li>
</ul>
</li>
<li><p>代码</p>
<ul>
<li>@FunctionalInterfacepublic interface MyInterface {<br>void show();<br>}</li>
</ul>
</li>
</ul>
<p>public class MyInterfaceDemo {<br>    public static void main(String[] args) {<br>        MyInterface my = () -&gt; System.out.println(“函数式接口”);<br>My.show();<br>    }<br>}</p>
<h3 id="02-函数式接口作为方法的参数"><a href="#02-函数式接口作为方法的参数" class="headerlink" title="02_函数式接口作为方法的参数"></a>02_函数式接口作为方法的参数</h3><ul>
<li><p>需求</p>
<ul>
<li>定义一个类(RunnableDemo)，在类中提供两个方法：</li>
<li>一个方法是：startThread(Runnable r)   方法参数Runnable是一个函数式接口。</li>
<li>一个方法是主方法，在主方法中调用startThread方法。</li>
<li>如果方法的参数是一个函数式接口，我们可以使用Lambda表达式作为参数传递。</li>
<li>startThread(() -&gt; System.out.printIn(Thread.currentThread().getName() + “线程启动了”));</li>
</ul>
</li>
<li><p>代码</p>
<ul>
<li>@FunctionalInterface<br>public interface Runnable {<br>public abstract void run();<br>}</li>
</ul>
</li>
</ul>
<p>public class RunnableDemo {<br> public static void main(String[] args) {<br>     startThread(new Runnable()){<br>         @Override<br>                 public void run(){<br>             System.out.println(“线程启动了”);<br>         }<br>     }<br>        MyInterface my = () -&gt;<br>    }<br>    private static void startThread(Runnable r)<br>    {<br>        new Thread(r).start();<br>    }<br>}</p>
<h3 id="03-函数式接口作为方法的返回值"><a href="#03-函数式接口作为方法的返回值" class="headerlink" title="03_函数式接口作为方法的返回值"></a>03_函数式接口作为方法的返回值</h3><ul>
<li><p>需求描述</p>
<ul>
<li>定义一个类(ComparatorDemo)，在类中提供两个方法：</li>
<li>一个方法是：Comparator<String> getComparator()   方法返回值Comparator是一个函数式接口。</li>
<li>一个方法是主方法，在主方法中调用getComparator方法。</li>
<li>如果方法的返回值是一个函数式接口，我们可以使用Lambda表达式作为结果返回。</li>
</ul>
</li>
<li><p>代码</p>
<ul>
<li>private static Comparator<String> getComparator() {<br>  return (s1, s2) -&gt; s1.length() - s2.length();</li>
</ul>
</li>
</ul>
<p>}</p>
<pre><code>- 子主题 2
- 子主题 3
</code></pre><h3 id="04-常用函数式接口之Supplier"><a href="#04-常用函数式接口之Supplier" class="headerlink" title="04_常用函数式接口之Supplier"></a>04_常用函数式接口之Supplier</h3><ul>
<li>Java8在java.util.function包下预定义了大量的函数式接口供我们使用。</li>
<li><p>我们重点来学习下面的4个接口：</p>
<ul>
<li><p>Supplier接口</p>
<ul>
<li>Supplier<T>：包含一个无参的方法。</li>
<li>T get()：获得结果。</li>
<li>该方法不需要参数，它会按照某种实现逻辑(由Lambda表达式实现)返回一个数据。</li>
<li>Supplier<T>接口也被称为生产型接口，如果我们指定了接口的泛型是什么类型，那么接口中的get方法就会生产什么类型的数据供我们使用。</li>
<li>常用方法：只有一个无参的方法。</li>
</ul>
</li>
<li><p>Consumer接口</p>
</li>
<li>Predicate接口</li>
<li>Function接口</li>
</ul>
</li>
<li><p>子主题 3</p>
</li>
<li>子主题 4</li>
<li>子主题 5</li>
<li>子主题 6</li>
<li>子主题 7</li>
</ul>
<h3 id="子主题-116"><a href="#子主题-116" class="headerlink" title="子主题 116"></a>子主题 116</h3><h3 id="05-Supplier接口练习之获取最大值"><a href="#05-Supplier接口练习之获取最大值" class="headerlink" title="05_Supplier接口练习之获取最大值"></a>05_Supplier接口练习之获取最大值</h3><ul>
<li><p>1.5、Supplier接口</p>
<ul>
<li>Supplier<T>：包含一个无参的方法。</li>
<li><p>T get()：获得结果。</p>
<ul>
<li>该方法不需要参数，它会按照某种实现逻辑(由Lambda表达式实现)返回一个数据。</li>
</ul>
</li>
<li><p>Supplier<T>接口也被称为生产型接口，如果我们指定了接口的泛型是什么类型，那么接口中的get方法就会生产什么类型的数据供我们使用。</p>
</li>
</ul>
</li>
<li><p>练习（案例需求）</p>
<ul>
<li><p>定义一个类(SupplierTest)，在类中提供两个方法：</p>
<ul>
<li>一个方法是：int getMax(Supplier<Integer> sup) 用于返回一个int数组中的最大值</li>
<li>一个方法是主方法，在主方法中调用getMax方法</li>
<li>public class SupplierTest {<br>//返回一个int数组的最大值<br>private static int getMax(Supplier<int> sup) {<br>return sup.get();<br>}</li>
</ul>
<p>public static void main(String[] args) {<br>  int[] arr = {19, 50, 658, 54, 5};<br>  int maxValue = getMax(() -&gt; {</p>
<pre><code>  int max = arr[0];
  for (int i = 1; i &lt; arr.length; i++) &#123;
      if (arr[i] &gt; max)
          max = arr[i];
  &#125;
  return max;
</code></pre><p>  });<br>}<br>}</p>
</li>
</ul>
</li>
</ul>
<h3 id="06-常用函数式接口之Consumer"><a href="#06-常用函数式接口之Consumer" class="headerlink" title="06_常用函数式接口之Consumer"></a>06_常用函数式接口之Consumer</h3><ul>
<li>Consumer<T>：包含两个方法。</li>
<li>void accept(T t)：对给定的参数执行此操作。</li>
<li>default Consumer<T> andThen(Consumer after)：返回一个组合的Consumer，依次执行此操作，然后执行 after操作。</li>
<li>Consumer<T>接口也被称为消费型接口，它消费的数据的数据类型由泛型指定。</li>
<li>public interface Cinsumer<T>{<br>  void accept(T t);<br>  default Consumer<T> andThen(Consumer&lt;? super T&gt;after){<pre><code>  Objects.requireNonNull(after);
  return (T t)-&gt;&#123;accept(t);after.accept(t);&#125;;
</code></pre>  }<br>}</li>
</ul>
<h3 id="07-Consumer接口练习之按要求打印信息"><a href="#07-Consumer接口练习之按要求打印信息" class="headerlink" title="07_Consumer接口练习之按要求打印信息"></a>07_Consumer接口练习之按要求打印信息</h3><ul>
<li>Consumer<T>：包含两个方法。</li>
<li>void accept(T t)：对给定的参数执行此操作。</li>
<li>default Consumer<T> andThen(Consumer after)：返回一个组合的Consumer，依次执行此操作，然后执行 after操作。</li>
<li>Consumer<T>接口也被称为消费型接口，它消费的数据的数据类型由泛型指定。</li>
<li><p>练习（案例需求）</p>
<ul>
<li>String[] strArray = {“林青霞,30”, “张曼玉,35”, “王祖贤,33”};</li>
<li>字符串数组中有多条信息，请按照格式：“姓名：XX,年龄：XX”的格式将信息打印出来。</li>
<li><p>要求：</p>
<ul>
<li>把打印姓名的动作作为第一个Consumer接口的Lambda实例。</li>
<li>把打印年龄的动作作为第二个Consumer接口的Lambda实例。</li>
<li>将两个Consumer接口按照顺序组合到一起使用。</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="08-常用函数式接口之Predicate-1"><a href="#08-常用函数式接口之Predicate-1" class="headerlink" title="08_常用函数式接口之Predicate(1)"></a>08_常用函数式接口之Predicate(1)</h3><ul>
<li><p>Predicate<T>：常用的四个方法：</p>
<ul>
<li>boolean test(T t)：对给定的参数进行判断(判断逻辑由Lambda表达式实现)，返回一个布尔值。</li>
<li>default Predicate<T> negate()：返回一个逻辑的否定，对应逻辑非。</li>
<li>default Predicate<T> and(Predicate other)：返回一个组合判断，对应短路与。</li>
<li>default Predicate<T> or(Predicate other)：返回一个组合判断，对应短路或。</li>
<li>Predicate<T>接口通常用于判断参数是否满足指定的条件。</li>
</ul>
</li>
</ul>
<h3 id="09-常用函数式接口之Predicate-2"><a href="#09-常用函数式接口之Predicate-2" class="headerlink" title="09_常用函数式接口之Predicate(2)"></a>09_常用函数式接口之Predicate(2)</h3><ul>
<li><p>Predicate<T>：常用的四个方法：</p>
<ul>
<li>boolean test(T t)：对给定的参数进行判断(判断逻辑由Lambda表达式实现)，返回一个布尔值。</li>
<li>default Predicate<T> negate()：返回一个逻辑的否定，对应逻辑非。</li>
<li>default Predicate<T> and(Predicate other)：返回一个组合判断，对应短路与。</li>
<li>default Predicate<T> or(Predicate other)：返回一个组合判断，对应短路或。</li>
<li>Predicate<T>接口通常用于判断参数是否满足指定的条件。</li>
</ul>
</li>
</ul>
<h3 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h3><ul>
<li>10_Predicate接口练习之筛选满足条件数据</li>
<li><p>Predicate<T>：常用的四个方法：</p>
<ul>
<li>boolean test(T t)：对给定的参数进行判断(判断逻辑由Lambda表达式实现)，返回一个布尔值。</li>
<li>default Predicate<T> negate()：返回一个逻辑的否定，对应逻辑非。</li>
<li>default Predicate<T> and(Predicate other)：返回一个组合判断，对应短路与。</li>
<li>default Predicate<T> or(Predicate other)：返回一个组合判断，对应短路或。</li>
</ul>
</li>
<li><p>Predicate<T>接口通常用于判断参数是否满足指定的条件。</p>
</li>
<li><p>练习描述</p>
<ul>
<li>String[] strArray = {“林青霞,30”, “柳岩,34”, “张曼玉,35”, “貂蝉,31”, “王祖贤,33”};</li>
<li>字符串数组中有多条信息，请通过Predicate接口的拼装 将符合要求的字符串筛选到集合ArrayList中，并遍历ArrayList集合。</li>
<li>同时满足如下要求：姓名长度大于2；年龄大于33。</li>
</ul>
</li>
<li><p>分析</p>
<ul>
<li>1.有两个判断条件,所以需要使用两个Predicate接口,对条件进行判断。</li>
<li>2.必须同时满足两个条件,所以可以使用and方法连接两个判断条件。</li>
</ul>
</li>
<li><p>代码</p>
</li>
</ul>
<h3 id="11-常用函数式接口之Function"><a href="#11-常用函数式接口之Function" class="headerlink" title="11_常用函数式接口之Function"></a>11_常用函数式接口之Function</h3><ul>
<li>Function<T,R>：常用的两个方法：</li>
<li>R apply​(T t)：将此函数应用于给定的参数。</li>
<li>default <V> Function andThen​(Function after)：返回一个组合函数，首先将该函数应用于输入，然后将after函数应用于结果。</li>
<li>Function<T,R>接口通常用于对参数进行处理，转换(处理逻辑由Lambda表达式实现)，然后返回一个新的值。</li>
<li><p>代码</p>
<ul>
<li>1.8、Function接口</li>
</ul>
</li>
<li><p>子主题 6</p>
</li>
</ul>
<h3 id="12-Function接口练习之按照指定要求操作数据"><a href="#12-Function接口练习之按照指定要求操作数据" class="headerlink" title="12_Function接口练习之按照指定要求操作数据"></a>12_Function接口练习之按照指定要求操作数据</h3><ul>
<li>Function<T,R>：常用的两个方法：</li>
<li>R apply​(T t)：将此函数应用于给定的参数。</li>
<li>default <V> Function andThen​(Function after)：返回一个组合函数，首先将该函数应用于输入，然后将after函数应用于结果。</li>
<li>Function<T,R>接口通常用于对参数进行处理，转换(处理逻辑由Lambda表达式实现)，然后返回一个新的值。</li>
<li><p>练习描述</p>
<ul>
<li>String s = “林青霞,30”;</li>
<li>请按照指定的要求进行操作：</li>
<li>将字符串截取得到数字年龄部分</li>
<li>将上一步的年龄字符串转换成为int类型的数据</li>
<li>将上一步的int数据加70，得到一个int结果，在控制台输出</li>
<li>请通过Function接口来实现函数拼接</li>
</ul>
</li>
<li><p>代码</p>
</li>
</ul>
<h3 id="13-体验Stream流"><a href="#13-体验Stream流" class="headerlink" title="13_体验Stream流"></a>13_体验Stream流</h3><ul>
<li><p>案例需求：按照下面的要求完成集合的创建和遍历。</p>
<ul>
<li>创建一个集合，存储多个字符串元素；</li>
<li>把集合中所有以”张”开头的元素存储到一个新的集合；</li>
<li>把”张”开头的集合中的长度为3的元素存储到一个新的集合；</li>
<li>遍历上一步得到的集合。</li>
<li>使用Stream流的方式完成过滤操作（Stream流的好处）：</li>
<li>list.stream().filter(s -&gt; s.startsWith(“张”)).filter(s -&gt; s.length() == 3).forEach(System.out::println);</li>
<li>直接阅读代码的字面意思，即可完美展示无关逻辑方式的语义：获取流、过滤姓张、过滤长度为3、逐一打印。</li>
<li>Stream流把真正的函数式编程风格引入到Java中。</li>
</ul>
</li>
<li><p>代码</p>
<ul>
<li>package com.itheima_01;</li>
</ul>
</li>
</ul>
<p>import java.util.ArrayList;</p>
<p>public class StreamDemo {<br>    public static void main(String[] args) {<br>        //1.创建一个集合，存储多个字符串元素<br>        ArrayList<String> list = new ArrayList<String>();<br>        list.add(“林青霞”);<br>        list.add(“张曼玉”);<br>        list.add(“王祖贤”);<br>        list.add(“柳岩”);<br>        list.add(“张敏”);<br>        list.add(“张无忌”);<br>        //2.把集合中所有以”张”开头的元素存储到一个新的集合<br>        ArrayList<String> zhangList = new ArrayList<String>();<br>        for (String s : list) {<br>            if (s.startsWith(“张”)) {<br>                zhangList.add(s);<br>            }<br>        }<br>        System.out.println(zhangList);<br>        //3.把”张”开头的集合中的长度为3的元素存储到一个新的集合<br>        ArrayList<String> threeList = new ArrayList<String>();<br>        for (String s : zhangList) {<br>            if (s.length() == 3) {<br>                threeList.add(s);<br>            }<br>        }<br>        System.out.println(threeList);<br>        //4.遍历上一步得到的集合<br>        for (String s : threeList) {<br>            System.out.println(s);<br>        }<br>        System.out.println(“————“);<br>        //Stream流来改进<br>        list.stream().filter(s -&gt; s.startsWith(“张”)).filter(s -&gt; s.length() == 3).forEach(s -&gt; System.out.println(s));<br>        list.stream().filter(s -&gt; s.startsWith(“张”)).filter(s -&gt; s.length() == 3).forEach(System.out::println);<br>    }<br>}</p>
<h3 id="14-Stream流的常见生成方式"><a href="#14-Stream流的常见生成方式" class="headerlink" title="14_Stream流的常见生成方式"></a>14_Stream流的常见生成方式</h3><ul>
<li>Stream流的思想</li>
<li><p>Stream流的使用</p>
<ul>
<li><p>生成流</p>
<ul>
<li>通过数据源(集合、数组等)生成流</li>
<li>list.stream()</li>
</ul>
</li>
<li><p>中间操作</p>
<ul>
<li>一个流后面可以跟随零个或多个中间操作，其目的主要是打开流，做出某种程度的数据过滤/映射，然后返回一个新的流，交给下一个操作使用</li>
<li>filter()</li>
</ul>
</li>
<li><p>终结操作</p>
<ul>
<li>一个流只能有一个终结操作，当这个操作执行后，流就被使用“光”了，无法再被操作。所以这必定是流的最后一个操作。</li>
<li>forEach()</li>
</ul>
</li>
</ul>
</li>
<li><p>Stream流的常见生成方式</p>
<ul>
<li>Collection体系的集合可以使用默认方法stream​()生成流</li>
<li>default Stream<E> stream​()</li>
<li>Map体系的集合间接的生成流</li>
<li>数组可以通过Stream接口的静态方法of​(T… values)生成流</li>
<li>package com.itheima_02;</li>
</ul>
</li>
<li><p>代码</p>
<ul>
<li>import java.util.*;<br>import java.util.stream.Stream;</li>
</ul>
</li>
</ul>
<p>public class StreamDemo {<br>    public static void main(String[] args) {<br>        //1.Collection体系的集合可以使用默认方法stream​()生成流<br>        List<String> list = new ArrayList<String>();<br>        Stream<String> listStream = list.stream();</p>
<pre><code>    Set&lt;String&gt; set = new HashSet&lt;String&gt;();
    Stream&lt;String&gt; setStream = set.stream();

    //2.Map体系的集合间接的生成流
    Map&lt;String, Integer&gt; map = new HashMap&lt;String, Integer&gt;();
    Stream&lt;String&gt; keyStream = map.keySet().stream();
    Stream&lt;Integer&gt; valueStream = map.values().stream();
    Stream&lt;Map.Entry&lt;String, Integer&gt;&gt; entryStream = map.entrySet().stream();

    //3.数组可以通过Stream接口的静态方法of​(T... values)生成流
    String[] strArray = &#123;&quot;hello&quot;, &quot;world&quot;, &quot;java&quot;&#125;;
    Stream&lt;String&gt; strArrayStream1 = Stream.of(strArray);
    Stream&lt;String&gt; strArrayStream2 = Stream.of(&quot;hello&quot;, &quot;world&quot;, &quot;java&quot;);
    Stream&lt;Integer&gt; intStream = Stream.of(10, 20, 30);
&#125;
</code></pre><p>}</p>
<h3 id="15-Stream流中间操作之filter"><a href="#15-Stream流中间操作之filter" class="headerlink" title="15_Stream流中间操作之filter"></a>15_Stream流中间操作之filter</h3><ul>
<li>概念：中间操作的意思是，执行完此方法之后，Stream流依然可以继续执行其他操作。</li>
<li>Stream<T> filter​(Predicate predicate)：用于对流中的数据进行过滤。</li>
<li>Predicate接口中的方法    boolean test​(T t)：对给定的参数进行判断，返回一个布尔值。</li>
<li><p>代码</p>
<ul>
<li>子主题 1</li>
</ul>
</li>
</ul>
<h3 id="16-Stream流中间操作之limit-amp-skip"><a href="#16-Stream流中间操作之limit-amp-skip" class="headerlink" title="16_Stream流中间操作之limit&amp;skip"></a>16_Stream流中间操作之limit&amp;skip</h3><ul>
<li>Stream<T> filter​(Predicate predicate)：用于对流中的数据进行过滤。</li>
<li>Predicate接口中的方法    boolean test​(T t)：对给定的参数进行判断，返回一个布尔值。</li>
<li>Stream<T> limit​(long maxSize)：返回此流中的元素组成的流，截取前指定参数个数的数据。</li>
<li>Stream<T> skip​(long n)：跳过指定参数个数的数据，返回由该流的剩余元素组成的流。</li>
<li><p>代码</p>
<ul>
<li>子主题 1</li>
</ul>
</li>
</ul>
<h3 id="17-Stream流中间操作之concat-amp-distinct"><a href="#17-Stream流中间操作之concat-amp-distinct" class="headerlink" title="17_Stream流中间操作之concat&amp;distinct"></a>17_Stream流中间操作之concat&amp;distinct</h3><ul>
<li><p>1.3、Stream流的常见中间操作方法</p>
<ul>
<li>Stream<T> filter​(Predicate predicate)：用于对流中的数据进行过滤。</li>
<li>Predicate接口中的方法    boolean test​(T t)：对给定的参数进行判断，返回一个布尔值。</li>
<li>Stream<T> limit​(long maxSize)：返回此流中的元素组成的流，截取前指定参数个数的数据。</li>
<li>Stream<T> skip​(long n)：跳过指定参数个数的数据，返回由该流的剩余元素组成的流。</li>
<li>static <T> Stream<T> concat​(Stream a, Stream b)：合并a和b两个流为一个流。</li>
<li>Stream<T> distinct​()：返回由该流的不同元素（根据Object.equals(Object) ）组成的流。</li>
</ul>
</li>
<li><p>代码</p>
<ul>
<li>子主题 1</li>
</ul>
</li>
</ul>
<h3 id="18-Stream流中间操作之sorted"><a href="#18-Stream流中间操作之sorted" class="headerlink" title="18_Stream流中间操作之sorted"></a>18_Stream流中间操作之sorted</h3><ul>
<li><p>1.3、Stream流的常见中间操作方法</p>
<ul>
<li>Stream<T> filter​(Predicate predicate)：用于对流中的数据进行过滤。</li>
<li>Predicate接口中的方法    boolean test​(T t)：对给定的参数进行判断，返回一个布尔值。</li>
<li>Stream<T> limit​(long maxSize)：返回此流中的元素组成的流，截取前指定参数个数的数据。</li>
<li>Stream<T> skip​(long n)：跳过指定参数个数的数据，返回由该流的剩余元素组成的流。</li>
<li>static <T> Stream<T> concat​(Stream a, Stream b)：合并a和b两个流为一个流。</li>
<li>Stream<T> distinct​()：返回由该流的不同元素（根据Object.equals(Object) ）组成的流。</li>
<li>Stream<T> sorted​()：返回由此流的元素组成的流，根据自然顺序排序。</li>
<li>Stream<T> sorted​(Comparator comparator)：返回由该流的元素组成的流，根据提供的Comparator进行排序。</li>
<li>Comparator接口中的方法int compare​(T o1, T o2)</li>
</ul>
</li>
<li><p>代码</p>
</li>
</ul>
<h3 id="19-Stream流中间操作之map-amp-mapToInt"><a href="#19-Stream流中间操作之map-amp-mapToInt" class="headerlink" title="19_Stream流中间操作之map&amp;mapToInt"></a>19_Stream流中间操作之map&amp;mapToInt</h3><ul>
<li><p>1.3、Stream流的常见中间操作方法</p>
<ul>
<li>概念：中间操作的意思是，执行完此方法之后，Stream流依然可以继续执行其他操作。</li>
<li>Stream<T> filter​(Predicate predicate)：用于对流中的数据进行过滤。</li>
<li>Predicate接口中的方法    boolean test​(T t)：对给定的参数进行判断，返回一个布尔值。</li>
<li>Stream<T> limit​(long maxSize)：返回此流中的元素组成的流，截取前指定参数个数的数据。</li>
<li>Stream<T> skip​(long n)：跳过指定参数个数的数据，返回由该流的剩余元素组成的流。</li>
<li>static <T> Stream<T> concat​(Stream a, Stream b)：合并a和b两个流为一个流。</li>
<li>Stream<T> distinct​()：返回由该流的不同元素（根据Object.equals(Object) ）组成的流。</li>
<li>Stream<T> sorted​()：返回由此流的元素组成的流，根据自然顺序排序。</li>
<li>Stream<T> sorted​(Comparator comparator)：返回由该流的元素组成的流，根据提供的Comparator进行排序。</li>
<li>Comparator接口中的方法    int compare​(T o1, T o2)</li>
<li><R> Stream<R> map​(Function mapper)：返回由给定函数应用于此流的元素的结果组成的流。</li>
</ul>
</li>
<li><p>代码</p>
</li>
<li><p>Function接口中的方法        R apply​(T t)</p>
<ul>
<li>IntStream mapToInt​(ToIntFunction mapper)：返回一个IntStream其中包含将给定函数应用于此流的元素的结果。</li>
<li>IntStream：表示原始 int 流</li>
<li>ToIntFunction接口中的方法     int applyAsInt​(T value)</li>
</ul>
</li>
</ul>
<h3 id="20-Stream流终结"><a href="#20-Stream流终结" class="headerlink" title="20_Stream流终结"></a>20_Stream流终结</h3><ul>
<li>概念：终结操作的意思是，执行完此方法之后，Stream流将不能再执行其他操作。</li>
<li><p>1.4、Stream流的常见终结操作方法</p>
<ul>
<li>void forEach(Consumer action)：对此流的每个元素执行操作。</li>
</ul>
</li>
<li><p>Consumer接口中的方法</p>
<ul>
<li>void accept​(T t)：对给定的参数执行此操作</li>
<li>long count()：返回此流中的元素数。</li>
</ul>
</li>
<li><p>代码</p>
</li>
</ul>
<h3 id="21-Stream流综合练习操作之forEach-amp-count"><a href="#21-Stream流综合练习操作之forEach-amp-count" class="headerlink" title="21_Stream流综合练习操作之forEach&amp;count"></a>21_Stream流综合练习操作之forEach&amp;count</h3><ul>
<li><p>案例需求：现在有两个ArrayList集合，分别存储6名男演员名称和6名女演员名称，要求完成如下的操作：</p>
<ul>
<li>男演员只要名字为3个字的前三人；</li>
<li>女演员只要姓林的，并且不要第一个；</li>
<li>把过滤后的男演员姓名和女演员姓名合并到一起；</li>
<li>把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据。</li>
<li>演员类Actor已经提供，里面有一个成员变量，一个带参构造方法，以及成员变量对应的get/set方法。</li>
</ul>
</li>
<li><p>代码</p>
<ul>
<li>子主题 2</li>
<li>子主题 3</li>
</ul>
</li>
</ul>
<h3 id="22-Stream流的收集操作"><a href="#22-Stream流的收集操作" class="headerlink" title="22_Stream流的收集操作"></a>22_Stream流的收集操作</h3><ul>
<li><p>概念：</p>
<ul>
<li>对数据使用Stream流的方式操作完毕后，可以把流中的数据收集到集合中。</li>
<li><p>Stream流的收集方法：</p>
<ul>
<li><p>R collect​(Collector collector)：把结果收集到集合中</p>
<ul>
<li><p>但是这个收集方法的参数是一个Collector接口。它是通过工具类Collectors提供了具体的收集方式：</p>
<ul>
<li>public static <T> Collector toList​()：把元素收集到List集合中</li>
<li>Public static <T> Collector toSet​()：把元素收集到Set集合中</li>
<li>Public static Collector toMap​(Function keyMapper,Function valueMapper)：把元素收集到Map集合中</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>代码</p>
<ul>
<li>package com.itheima_06;</li>
</ul>
</li>
</ul>
<p>import java.util.*;<br>import java.util.stream.Collectors;<br>import java.util.stream.Stream;</p>
<p>public class CollectDemo {<br>    public static void main(String[] args) {<br>        //创建List集合对象<br>        List<String> list = new ArrayList<String>();<br>        list.add(“林青霞”);<br>        list.add(“张曼玉”);<br>        list.add(“王祖贤”);<br>        list.add(“柳岩”);</p>
<pre><code>    //需求1：得到名字为3个字的流
    Stream&lt;String&gt; listStream = list.stream().filter(s -&gt; s.length() == 3);

    //需求2：把使用Stream流操作完毕的数据收集到List集合中并遍历
    List&lt;String&gt; names = listStream.collect(Collectors.toList());
    for (String name : names) &#123;
        System.out.println(name);
    &#125;

    //创建Set集合对象
    Set&lt;Integer&gt; set = new HashSet&lt;Integer&gt;();
    set.add(10);
    set.add(20);
    set.add(30);
    set.add(33);
    set.add(35);

    //需求3：得到年龄大于25的流
    Stream&lt;Integer&gt; setStream = set.stream().filter(age -&gt; age &gt; 25);

    //需求4：把使用Stream流操作完毕的数据收集到Set集合中并遍历
    Set&lt;Integer&gt; ages = setStream.collect(Collectors.toSet());
    for (Integer age : ages) &#123;
        System.out.println(age);
    &#125;

    //定义一个字符串数组，每一个字符串数据由姓名数据和年龄数据组合而成
    String[] strArray = &#123;&quot;林青霞,30&quot;, &quot;张曼玉,35&quot;, &quot;王祖贤,33&quot;, &quot;柳岩,25&quot;&#125;;

    //需求5：得到字符串中年龄数据大于28的流
    Stream&lt;String&gt; arrayStream = Stream.of(strArray).filter(s -&gt; Integer.parseInt(s.split(&quot;,&quot;)[1]) &gt; 28);

    //需求6：把使用Stream流操作完毕的数据收集到Map集合中并遍历，字符串中的姓名作键，年龄作值
    Map&lt;String, Integer&gt; map = arrayStream.collect(Collectors.toMap(s -&gt; s.split(&quot;,&quot;)[0], s -&gt; Integer.parseInt(s.split(&quot;,&quot;)[1])));

    Set&lt;String&gt; keySet = map.keySet();
    for (String key : keySet) &#123;
        Integer value = map.get(key);
        System.out.println(key + &quot;,&quot; + value);
    &#125;

&#125;
</code></pre><p>}</p>
<ul>
<li><p>01_类加载</p>
<ul>
<li><p>类加载的描述</p>
<ul>
<li>当程序要使用某个类时，如果该类还未被加载到内存中，则系统会通过类的加载、类的连接、类的初始化这三个步骤来对类进行初始化。如果不出现意外情况，JVM将会连续完成这三个步骤，所以有时也把这三个步骤统称为类加载或者类初始化。</li>
</ul>
</li>
<li><p>类的加载</p>
<ul>
<li>就是指将class文件读入内存，并为之创建一个 java.lang.Class对象</li>
<li>任何类被使用时，系统都会为之建立一个 java.lang.Class 对象</li>
</ul>
</li>
<li><p>类的连接</p>
<ul>
<li>验证阶段：用于检验被加载的类是否有正确的内部结构，并和其他类协调一致</li>
<li>准备阶段：负责为类的类变量分配内存，并设置默认初始化值</li>
<li>解析阶段：将类的二进制数据中的符号引用替换为直接引用</li>
</ul>
</li>
<li><p>类的初始化</p>
<ul>
<li>在该阶段，主要就是对类变量进行初始化</li>
</ul>
</li>
<li><p>类的初始化步骤</p>
<ul>
<li>假如类还未被加载和连接，则程序先加载并连接该类</li>
<li>假如该类的直接父类还未被初始化，则先初始化其直接父类</li>
<li>假如类中有初始化语句，则系统依次执行这些初始化语句</li>
<li>注意：在执行第2个步骤的时候，系统对直接父类的初始化步骤也遵循初始化步骤1-3</li>
</ul>
</li>
<li><p>类的初始化时机：</p>
<ul>
<li>创建类的实例</li>
<li>调用类的类方法</li>
<li>访问类或者接口的类变量，或者为该类变量赋值</li>
<li>使用反射方式来强制创建某个类或接口对应的java.lang.Class对象</li>
<li>初始化某个类的子类</li>
<li>直接使用java.exe命令来运行某个主类</li>
</ul>
</li>
</ul>
</li>
<li><p>02_类加载器</p>
<ul>
<li><p>类加载器的作用：</p>
<ul>
<li>负责将.class文件加载到内存中，并为之生成对应的 java.lang.Class 对象。</li>
<li>虽然我们不用过分关心类加载机制，但是了解这个机制我们就能更好的理解程序的运行！</li>
</ul>
</li>
<li><p>JVM的类加载机制：</p>
<ul>
<li>全盘负责：就是当一个类加载器负责加载某个Class时，该Class所依赖的和引用的其他Class也将由该类加载器负责载入，除非显示使用另外一个类加载器来载入。</li>
<li>父类委托：就是当一个类加载器负责加载某个Class时，先让父类加载器试图加载该Class，只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类。</li>
<li>缓存机制：保证所有加载过的Class都会被缓存，当程序需要使用某个Class对象时，类加载器先从缓存区中搜索该Class，只有当缓存区中不存在该Class对象时，系统才会读取该类对应的二进制数据，并将其转换成Class对象，存储到缓存区。</li>
</ul>
</li>
<li><p>ClassLoader：是负责加载类的对象。</p>
</li>
<li><p>Java运行时，具有以下内置类加载器：</p>
<ul>
<li>Bootstrap class loader：它是虚拟机的内置类加载器，通常表示为null ，并且没有父null。</li>
<li>Platform class loader：平台类加载器可以看到所有平台类 ，平台类包括由平台类加载器或其祖先定义的Java SE平台API，其实现类和JDK特定的运行时类。</li>
<li>System class loader：它也被称为应用程序类加载器 ，与平台类加载器不同。系统类加载器通常用于定义应用程序类路径，模块路径和JDK特定工具上的类。</li>
<li>类加载器的继承关系：System的父加载器为Platform，而Platform的父加载器为Bootstrap。</li>
</ul>
</li>
<li><p>ClassLoader中的两个方法：</p>
<ul>
<li>static ClassLoader getSystemClassLoader()：返回用于委派的系统类加载器</li>
<li>ClassLoader getParent()：返回父类加载器进行委派</li>
</ul>
</li>
</ul>
</li>
<li><p>03_反射概述</p>
<ul>
<li>Java反射机制：是指在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象，调用方法的一种机制。由于这种动态性，可以极大的增强程序的灵活性，程序不用在编译期就完成确定，在运行期仍然可以扩展。</li>
</ul>
</li>
<li><p>04_获取Class类的对象</p>
<ul>
<li><p>我们要想通过反射去使用一个类，首先我们要获取到该类的字节码文件对象，也就是类型为Class类型的对象。这里我们提供三种方式获取Class类型的对象：</p>
<ul>
<li>类名.class属性</li>
<li>对象名.getClass()方法</li>
<li>Class.forName(全类名)方法</li>
</ul>
</li>
<li><p>使用类的class属性来获取该类对应的Class对象。</p>
<ul>
<li>举例: Student.class将会返回Student类对应的Class对象。</li>
</ul>
</li>
<li><p>调用对象的getClass()方法，返回该对象所属类对应的Class对象</p>
</li>
<li>该方法是Object类中的方法，所有的Java对象都可以调用该方法</li>
<li>使用Class类中的静态方法forName(String className)，该方法需要传入字符串参数，该字符串参数的值是某个类的全路径，也就是完整包名的路径。</li>
</ul>
</li>
<li><p>05_反射获取构造方法并使用</p>
<ul>
<li><p>Class类中用于获取构造方法的方法</p>
<ul>
<li>Constructor&lt;?&gt;[] getConstructors()：返回所有公共构造方法对象的数组</li>
<li>Constructor&lt;?&gt;[] getDeclaredConstructors()：返回所有构造方法对象的数组</li>
<li>Constructor<T> getConstructor(Class&lt;?&gt;… parameterTypes)：返回单个公共构造方法对象</li>
<li>Constructor<T> getDeclaredConstructor(Class&lt;?&gt;… parameterTypes)：返回单个构造方法对象</li>
</ul>
</li>
<li><p>Constructor类中用于创建对象的方法</p>
<ul>
<li>T newInstance(Object…initargs)：根据指定的构造方法创建对象</li>
</ul>
</li>
<li><p>代码</p>
<ul>
<li>package com.itheima_03;</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>import com.itheima_02.Student;</p>
<p>import java.lang.reflect.Constructor;<br>import java.lang.reflect.InvocationTargetException;</p>
<p>/<em><br>    反射获取构造方法并使用
 </em>/<br>public class ReflectDemo01 {<br>    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {<br>        //获取Class对象<br>        Class&lt;?&gt; c = Class.forName(“com.itheima_02.Student”);</p>
<pre><code>    //Constructor&lt;?&gt;[] getConstructors​() 返回一个包含 Constructor对象的数组， Constructor对象反映了由该 Class对象表示的类的所有公共构造函数
    Constructor&lt;?&gt;[] cons = c.getConstructors();
    for (Constructor con : cons) &#123;
        System.out.println(con);
    &#125;
    System.out.println(&quot;--------&quot;);
    //Constructor&lt;?&gt;[] getDeclaredConstructors​() 返回反映由该 Class对象表示的类声明的所有构造函数的 Constructor对象的数组
    Constructor&lt;?&gt;[] cons2 = c.getDeclaredConstructors();
    for (Constructor con : cons2) &#123;
        System.out.println(con);
    &#125;
    System.out.println(&quot;--------&quot;);

    //Constructor&lt;T&gt; getConstructor​(Class&lt;?&gt;... parameterTypes) 返回一个 Constructor对象，该对象反映由该 Class对象表示的类的指定公共构造函数
    //Constructor&lt;T&gt; getDeclaredConstructor​(Class&lt;?&gt;... parameterTypes) 返回一个 Constructor对象，该对象反映由此 Class对象表示的类或接口的指定构造函数
    //参数：你要获取的构造方法的参数的个数和数据类型对应的字节码文件对象

    Constructor&lt;?&gt; con = c.getConstructor();

    //Constructor提供了一个类的单个构造函数的信息和访问权限
    //T newInstance​(Object... initargs) 使用由此 Constructor对象表示的构造函数，使用指定的初始化参数来创建和初始化构造函数的声明类的新实例
    Object obj = con.newInstance();
    System.out.println(obj);

    Student s = new Student();
    System.out.println(s);
&#125;
</code></pre><p>}</p>
<ul>
<li><p>06_反射获取构造方法并使用练习</p>
<ul>
<li><p>练习1：通过反射获取公共的构造方法并创建对象。</p>
<ul>
<li><p>public class ReflectDemo02 {<br>public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {<br>//获取Class对象<br>Class&lt;?&gt; c = Class.forName(“com.itheima_02.Student”);</p>
<p>//public Student(String name, int age, String address)<br>//Constructor<T> getConstructor​(Class&lt;?&gt;… parameterTypes)<br>Constructor&lt;?&gt; con = c.getConstructor(String.class, int.class, String.class);<br>//基本数据类型也可以通过.class得到对应的Class类型</p>
<p>//T newInstance​(Object… initargs)<br>Object obj = con.newInstance(“林青霞”, 30, “西安”);<br>System.out.println(obj);<br>}<br>}<br>基本数据类型也可以通过.class得到对应的Class类型。</p>
</li>
</ul>
</li>
<li><p>练习2：案例需求：通过反射获取私有构造方法并创建对象。</p>
<ul>
<li>Student s = new Student(“林青霞”);<br>System.out.println(s);<br>public void setAccessible​(boolean flag)：值为true，取消访问检查</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>package com.itheima_03;</p>
<p>import java.lang.reflect.Constructor;<br>import java.lang.reflect.InvocationTargetException;</p>
<p>public class ReflectDemo03 {<br>    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {<br>        //获取Class对象<br>        Class&lt;?&gt; c = Class.forName(“com.itheima_02.Student”);</p>
<pre><code>    //private Student(String name)
    //Constructor&lt;T&gt; getDeclaredConstructor​(Class&lt;?&gt;... parameterTypes)
    Constructor&lt;?&gt; con = c.getDeclaredConstructor(String.class);

    //暴力反射
    //public void setAccessible​(boolean flag):值为true，取消访问检查
    con.setAccessible(true);

    Object obj = con.newInstance(&quot;林青霞&quot;);
    System.out.println(obj);

&#125;
</code></pre><p>}</p>
<h3 id="代码-1"><a href="#代码-1" class="headerlink" title="代码"></a>代码</h3><ul>
<li><p>08_反射获取成员变量并使用</p>
<ul>
<li><p>Class类中用于获取成员变量的方法</p>
<ul>
<li>Field[] getFields()：返回所有公共成员变量对象的数组</li>
<li>Field[] getDeclaredFields()：返回所有成员变量对象的数组</li>
<li>Field getField(String name)：返回单个公共成员变量对象</li>
<li>Field getDeclaredField(String name)：返回单个成员变量对象</li>
</ul>
</li>
<li><p>Field类中用于给成员变量赋值的方法</p>
<ul>
<li>void set(Object obj, Object value)：给obj对象的成员变量赋值为value</li>
<li>Class Class<T></li>
</ul>
</li>
<li><p>代码</p>
<ul>
<li>package com.itheima_04;</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>import com.itheima_02.Student;</p>
<p>import java.lang.reflect.Constructor;<br>import java.lang.reflect.Field;<br>import java.lang.reflect.InvocationTargetException;</p>
<p>/<em><br>    反射获取成员变量并使用
 </em>/<br>public class ReflectDemo01 {<br>    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {<br>        //获取Class对象<br>        Class&lt;?&gt; c = Class.forName(“com.itheima_02.Student”);</p>
<pre><code>    //Field[] getFields​() 返回一个包含 Field对象的数组， Field对象反映由该 Class对象表示的类或接口的所有可访问的公共字段
    //Field[] getDeclaredFields​() 返回一个 Field对象的数组，反映了由该 Class对象表示的类或接口声明的所有字段
</code></pre><p>//        Field[] fields = c.getFields();<br>        Field[] fields = c.getDeclaredFields();<br>        for(Field field : fields) {<br>            System.out.println(field);<br>        }<br>        System.out.println(“————“);</p>
<pre><code>    //Field getField​(String name) 返回一个 Field对象，该对象反映由该 Class对象表示的类或接口的指定公共成员字段
    //Field getDeclaredField​(String name) 返回一个 Field对象，该对象反映由该 Class对象表示的类或接口的指定声明字段
    Field addressField = c.getField(&quot;address&quot;);

    //获取无参构造方法创建对象
    Constructor&lt;?&gt; con = c.getConstructor();
    Object obj = con.newInstance();
</code></pre><p>//        obj.addressField = “西安”;</p>
<pre><code>    //Field提供有关类或接口的单个字段的信息和动态访问
    //void set​(Object obj, Object value) 将指定的对象参数中由此 Field对象表示的字段设置为指定的新值
    addressField.set(obj,&quot;西安&quot;); //给obj的成员变量addressField赋值为西安

    System.out.println(obj);
</code></pre><p>//        Student s = new Student();<br>//        s.address = “西安”;<br>//        System.out.println(s);<br>    }<br>}</p>
<ul>
<li><p>09_反射获取成员变量并使用练习</p>
<ul>
<li><p>练习：voidset(Object obj,Object value)：给obj对象的成员变量赋值为value</p>
<ul>
<li>Student s = new Student();<br>s.name = “林青霞”;<br>s.age = 30;<br>s.address = “西安”;<br>System.out.println(s);</li>
<li>package com.itheima_04;</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>import java.lang.reflect.Constructor;<br>import java.lang.reflect.Field;<br>import java.lang.reflect.InvocationTargetException;</p>
<p>public class ReflectDemo02 {<br>    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {<br>        //获取Class对象<br>        Class&lt;?&gt; c = Class.forName(“com.itheima_02.Student”);</p>
<pre><code>    //Student s = new Student();
    Constructor&lt;?&gt; con = c.getConstructor();
    Object obj = con.newInstance();
    System.out.println(obj);

    //s.name = &quot;林青霞&quot;;
</code></pre><p>//        Field nameField = c.getField(“name”); //NoSuchFieldException: name<br>        Field nameField = c.getDeclaredField(“name”);<br>        nameField.setAccessible(true);<br>        nameField.set(obj, “林青霞”);<br>        System.out.println(obj);</p>
<pre><code>    //s.age = 30;
    Field ageField = c.getDeclaredField(&quot;age&quot;);
    ageField.setAccessible(true);
    ageField.set(obj, 30);
    System.out.println(obj);

    //s.address = &quot;西安&quot;;
    Field addressField = c.getDeclaredField(&quot;address&quot;);
    addressField.setAccessible(true);
    addressField.set(obj, &quot;西安&quot;);
    System.out.println(obj);
&#125;
</code></pre><p>}</p>
<h3 id="代码-2"><a href="#代码-2" class="headerlink" title="代码"></a>代码</h3><h3 id="代码-3"><a href="#代码-3" class="headerlink" title="代码"></a>代码</h3><h3 id="代码-4"><a href="#代码-4" class="headerlink" title="代码"></a>代码</h3><h3 id="代码-5"><a href="#代码-5" class="headerlink" title="代码"></a>代码</h3>
      
    </div>
    <footer class="article-footer">
      <a data-url="https://goofyer.gitee.io/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E4%B8%80%E7%AB%A0%E5%87%BD%E6%95%B0%E5%BC%8F%E6%8E%A5%E5%8F%A3/" data-id="cl403sxrb001rf8vudwzq11vw" data-title="" class="article-share-link">Share</a>
      
      
      
    </footer>
  </div>
  
</article>



  
    <article id="post-Java/第十章 Lambda表达式" class="h-entry article article-type-post" itemprop="blogPost" itemscope itemtype="https://schema.org/BlogPosting">
  <div class="article-meta">
    <a href="/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E7%AB%A0%20Lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F/" class="article-date">
  <time class="dt-published" datetime="2021-12-19T17:32:59.257Z" itemprop="datePublished">2021-12-20</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
    <div class="e-content article-entry" itemprop="articleBody">
      
        <h2 id="第十章-Lambda表达式"><a href="#第十章-Lambda表达式" class="headerlink" title="第十章 Lambda表达式"></a>第十章 Lambda表达式</h2><h3 id="01-体验Lambda表达式"><a href="#01-体验Lambda表达式" class="headerlink" title="01_体验Lambda表达式"></a>01_体验Lambda表达式</h3><ul>
<li><p>1.1、函数式编程思想概述</p>
<ul>
<li>在数学中，函数就是有输入量、输出量的一套计算方案，也就是“拿数据做操作”。面向对象思想强调“必须通过对象的形式来做事情”。函数式思想则尽量忽略面向对象的复杂语法：“强调做什么，而不是以什么形式去做”。而我们要学习的Lambda表达式就是函数式思想的体现。</li>
</ul>
</li>
<li><p>1.2、体验Lambda表达式</p>
<ul>
<li><p>案例需求：</p>
<ul>
<li>启动一个线程，在控制台输出一句话：多线程程序启动了。</li>
</ul>
</li>
<li><p>实现方式1：</p>
<ul>
<li>定义一个类MyRunnable实现Runnable接口，重写run()方法</li>
<li>创建MyRunnable类的对象</li>
<li>创建Thread类的对象，把MyRunnable的对象作为构造参数传递</li>
<li>启动线程</li>
</ul>
</li>
<li><p>实现方式2：</p>
<ul>
<li>匿名内部类的方式改进</li>
</ul>
</li>
<li><p>实现方式3：</p>
<ul>
<li>Lambda表达式的方式改进</li>
</ul>
</li>
<li><p>代码如下</p>
<ul>
<li><p>public class MyRunnable implements  Runnable{<br>@Override<br>public void run() {<br>System.out.println(“多线程程序启动”);<br>}<br>}</p>
</li>
<li><p>public class LambdaDemo {<br>public static void main(String[]args)<br>{<br>//实现类的方法<br>MyRunnable my=new MyRunnable();<br>Thread t=new Thread(my);<br>t.start();</p>
<p>//匿名内部类<br>new Thread(new Runnable() {<br>  @Override<br>  public void run() {</p>
<pre><code>  System.out.println(&quot;多线程程序启动&quot;);
</code></pre><p>  }<br>}).start();<br>//lambda</p>
<p>new Thread(()-&gt;{<br>  System.out.println(“多线程程序启动”);<br>}).start();<br>}<br>}</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="02-Lambda表达式的标准格式"><a href="#02-Lambda表达式的标准格式" class="headerlink" title="02_Lambda表达式的标准格式"></a>02_Lambda表达式的标准格式</h3><ul>
<li><p>1.3、Lambda表达式的标准格式</p>
<ul>
<li>格式：(形式参数) -&gt; {代码块}</li>
<li>形式参数：如果有多个参数，参数之间用逗号隔开；如果没有参数，留空即可。</li>
<li>-&gt;：由英文中画线和大于符号组成，固定写法。代表指向动作。</li>
<li>代码块：是我们具体要做的事情，也就是以前我们写的方法体内容。</li>
</ul>
</li>
</ul>
<h3 id="03-Lambda表达式练习1-抽象方法无参无返回值"><a href="#03-Lambda表达式练习1-抽象方法无参无返回值" class="headerlink" title="03_Lambda表达式练习1(抽象方法无参无返回值)"></a>03_Lambda表达式练习1(抽象方法无参无返回值)</h3><ul>
<li><p>1.4、Lambda表达式的练习</p>
<ul>
<li><p>Lambda表达式的使用前提：</p>
<ul>
<li>有一个接口。</li>
<li>接口中有且仅有一个抽象方法。</li>
</ul>
</li>
<li><p>练习描述</p>
<ul>
<li>无参无返回值抽象方法的练习。</li>
</ul>
</li>
<li><p>练习1 操作步骤</p>
<ul>
<li>1.定义一个接口(Eatable)，里面定义一个抽象方法：void eat();</li>
<li><p>2.定义一个测试类(EatableDemo)，在测试类中提供两个方法：</p>
<ul>
<li>一个方法是：useEatable(Eatable e)</li>
<li>一个方法是主方法，在主方法中调用useEatable方法</li>
</ul>
</li>
</ul>
</li>
<li><p>代码</p>
<ul>
<li>public interface Eatable {<br>void eat();<br>}<br>public class EatableImpl implements Eatable{<br>@Override<br>public void eat() {<br>System.out.println(“一天一苹果”);<br>}<br>}<br>import java.sql.Statement;</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>public class EatableDemo {<br>    public static void useEatable(Eatable e)<br>    {<br>        e.eat();<br>    }<br>    public static void main(String[]args) {<br>        //实现类的方法调用方法<br>        Eatable e=new EatableImpl();//多态<br>        useEatable(e);<br>        //匿名内部类<br>        useEatable(new Eatable() {<br>            @Override<br>            public void eat() {<br>                System.out.println(“一天一苹果”);<br>            }<br>        });<br>        //lambda</p>
<pre><code>    useEatable(()-&gt;&#123;
        System.out.println(&quot;一天一苹果&quot;);
    &#125;);
&#125;
</code></pre><p>}</p>
<h3 id="04-Lambda表达式练习2-抽象方法带参无返回值"><a href="#04-Lambda表达式练习2-抽象方法带参无返回值" class="headerlink" title="04_Lambda表达式练习2(抽象方法带参无返回值)"></a>04_Lambda表达式练习2(抽象方法带参无返回值)</h3><ul>
<li><p>练习描述</p>
<ul>
<li>有参无返回值抽象方法的练习。</li>
</ul>
</li>
<li><p>练习2 操作步骤</p>
<ul>
<li>1.定义一个接口(Flyable)，里面定义一个抽象方法：void fly(String s);</li>
<li><p>2.定义一个测试类(FlyableDemo)，在测试类中提供两个方法：</p>
<ul>
<li>一个方法是：useFlyable(Flyable f)</li>
<li>一个方法是主方法，在主方法中调用useFlyable方法</li>
</ul>
</li>
</ul>
</li>
<li><p>代码</p>
</li>
</ul>
<h3 id="05-Lambda表达式练习3-抽象方法带参带返回值"><a href="#05-Lambda表达式练习3-抽象方法带参带返回值" class="headerlink" title="05_Lambda表达式练习3(抽象方法带参带返回值)"></a>05_Lambda表达式练习3(抽象方法带参带返回值)</h3><ul>
<li><p>练习描述</p>
<ul>
<li>有参有返回值抽象方法的练习。</li>
</ul>
</li>
<li><p>练习3 操作步骤</p>
<ul>
<li>定义一个接口(Addable)，里面定义一个抽象方法：int add(int x,int y);</li>
<li><p>定义一个测试类(AddableDemo)，在测试类中提供两个方法：</p>
<ul>
<li>一个方法是：useAddable(Addable a)</li>
<li>一个方法是主方法，在主方法中调用useAddable方法</li>
</ul>
</li>
</ul>
</li>
<li><p>代码</p>
</li>
</ul>
<h3 id="06-Lambda表达式的省略模式"><a href="#06-Lambda表达式的省略模式" class="headerlink" title="06_Lambda表达式的省略模式"></a>06_Lambda表达式的省略模式</h3><ul>
<li>1.5、Lambda表达式的省略模式</li>
<li><p>省略的规则：</p>
<ul>
<li>参数类型可以省略。但是有多个参数的情况下，不能只省略一个。</li>
<li>如果参数有且仅有一个，那么小括号可以省略。</li>
<li>如果代码块的语句只有一条，可以省略大括号和分号，和return关键字。</li>
</ul>
</li>
<li><p>代码</p>
</li>
<li>子主题 4</li>
</ul>
<h3 id="07-Lambda表达式的注意事项"><a href="#07-Lambda表达式的注意事项" class="headerlink" title="07_Lambda表达式的注意事项"></a>07_Lambda表达式的注意事项</h3><ul>
<li>1.6、Lambda表达式的注意事项</li>
<li><p>注意事项：</p>
<ul>
<li>使用Lambda必须要有接口，并且要求接口中有且仅有一个抽象方法。</li>
<li>必须有上下文环境，才能推导出Lambda对应的接口。</li>
<li>根据局部变量的赋值得知Lambda对应的接口：Runnable r = () -&gt; System.out.println(“Lambda表达式”);</li>
<li>根据调用方法的参数得知Lambda对应的接口：new Thread(() -&gt; System.out.println(“Lambda表达式”)).start();</li>
</ul>
</li>
<li><p>代码</p>
<ul>
<li>子主题 1</li>
<li>子主题 2</li>
</ul>
</li>
</ul>
<h3 id="08-Lambda表达式和匿名内部类的区别"><a href="#08-Lambda表达式和匿名内部类的区别" class="headerlink" title="08_Lambda表达式和匿名内部类的区别"></a>08_Lambda表达式和匿名内部类的区别</h3><ul>
<li><p>1.7、Lambda表达式和匿名内部类的区别</p>
<ul>
<li><p>所需类型不同</p>
<ul>
<li>匿名内部类：可以是接口，也可以是抽象类，还可以是具体类。</li>
<li>Lambda表达式：只能是接口。</li>
</ul>
</li>
<li><p>使用限制不同</p>
<ul>
<li>如果接口中有且仅有一个抽象方法，可以使用Lambda表达式，也可以使用匿名内部类。</li>
<li>如果接口中多于一个抽象方法，只能使用匿名内部类，而不能使用Lambda表达式。</li>
</ul>
</li>
<li><p>实现原理不同</p>
<ul>
<li>匿名内部类：编译之后，产生一个单独的.class字节码文件。</li>
<li>Lambda表达式：编译之后，没有一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成。</li>
</ul>
</li>
<li><p>子主题 4</p>
<ul>
<li>子主题 5</li>
<li>子主题 6</li>
<li>子主题 7</li>
<li>子主题 8</li>
<li>子主题 9</li>
<li>子主题 10</li>
<li>子主题 11</li>
<li>子主题 12</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="09-接口组成更新概述"><a href="#09-接口组成更新概述" class="headerlink" title="09_接口组成更新概述"></a>09_接口组成更新概述</h3><ul>
<li><p>常量</p>
<ul>
<li>public static final</li>
</ul>
</li>
<li><p>抽象方法</p>
<ul>
<li><p>public abstract</p>
<ul>
<li>子主题 1</li>
<li></li>
<li>子主题 1</li>
</ul>
</li>
<li><p>默认方法(Java 8)</p>
<ul>
<li><p>接口中默认方法的定义格式：</p>
<ul>
<li>格式：public default 返回值类型 方法名(参数列表) { }</li>
<li>范例：public default void show3() { }</li>
</ul>
</li>
<li><p>接口中默认方法的注意事项：</p>
<ul>
<li>默认方法不是抽象方法，所以不强制被重写。但是可以被重写，重写的时候去掉default关键字。</li>
<li>public可以省略，default不能省略。</li>
</ul>
</li>
<li><p>子主题 1</p>
</li>
</ul>
</li>
<li><p>静态方法(Java 8)</p>
</li>
<li>私有方法(Java 9)</li>
</ul>
</li>
</ul>
<h3 id="10-接口中默认方法"><a href="#10-接口中默认方法" class="headerlink" title="10_接口中默认方法"></a>10_接口中默认方法</h3><ul>
<li><p>1.2、接口中默认方法</p>
<ul>
<li><p>接口中默认方法的定义格式：</p>
<ul>
<li>格式：public default 返回值类型 方法名(参数列表) { }</li>
<li>范例：public default void show3() { }</li>
</ul>
</li>
<li><p>接口中默认方法的注意事项：</p>
<ul>
<li>默认方法不是抽象方法，所以不强制被重写。但是可以被重写，重写的时候去掉default关键字。</li>
<li>public可以省略，default不能省略。</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="11-接口中静态方法"><a href="#11-接口中静态方法" class="headerlink" title="11_接口中静态方法"></a>11_接口中静态方法</h3><ul>
<li><p>接口中静态方法的定义格式：</p>
<ul>
<li>格式：public static 返回值类型 方法名(参数列表) { }</li>
<li>范例：public static void show() { }</li>
</ul>
</li>
<li><p>接口中静态方法的注意事项：</p>
<ul>
<li>静态方法只能通过接口名调用，不能通过实现类名或者对象名调用。</li>
<li>public可以省略，static不能省略。</li>
</ul>
</li>
</ul>
<h3 id="12-接口中私有方法"><a href="#12-接口中私有方法" class="headerlink" title="12_接口中私有方法"></a>12_接口中私有方法</h3><ul>
<li><p>私有方法产生原因：</p>
<ul>
<li>Java 9中新增了带方法体的私有方法，这其实在Java 8中就埋下了伏笔：Java 8允许在接口中定义带方法体的默认方法和静态方法。这样可能会引发一个问题：当两个默认方法或者静态方法中包含一段相同的代码实现时，程序必然考虑将这段实现代码抽取成一个共性方法，而这个共性方法是不需要让别人使用的，因此用私有给隐藏起来，这就是Java 9增加私有方法的必然性。</li>
</ul>
</li>
<li><p>接口中私有方法的定义格式：</p>
<ul>
<li>格式1：private 返回值类型 方法名(参数列表) { }</li>
<li>范例1：private void show() { }</li>
<li>格式2：private static 返回值类型 方法名(参数列表) { }</li>
<li>范例2：private static void method() { }</li>
</ul>
</li>
<li><p>接口中私有方法的注意事项：</p>
<ul>
<li>默认方法可以调用私有的静态方法和非静态方法。</li>
<li>静态方法只能调用私有的静态方法。</li>
</ul>
</li>
</ul>
<h3 id="13-体验方法引用"><a href="#13-体验方法引用" class="headerlink" title="13_体验方法引用"></a>13_体验方法引用</h3><ul>
<li><p>方法引用的出现原因：</p>
<ul>
<li>在使用Lambda表达式的时候，我们实际上传递进去的代码就是一种解决方案：拿参数做操作。</li>
</ul>
</li>
<li><p>代码</p>
</li>
</ul>
<h3 id="14-方法引用符"><a href="#14-方法引用符" class="headerlink" title="14_方法引用符"></a>14_方法引用符</h3><ul>
<li><p>方法引用符：</p>
<ul>
<li>该符号为引用运算符，而它所在的表达式被称为方法引用。</li>
</ul>
</li>
<li><p>Lambda表达式：usePrintable(s -&gt; System.out.println(s));</p>
</li>
<li>分析：拿到参数s之后，通过Lambda表达式，传递给System.out.println方法去处理。</li>
<li>方法引用：usePrintable(System.out::println);</li>
<li>分析：直接使用System.out中的println方法来取代Lambda，代码更加的简洁。</li>
<li><p>推导与省略：</p>
<ul>
<li>如果使用Lambda，那么根据“可推导就是可省略”的原则，无需指定参数类型也无需指定的重载形式， 它们都将被自动推导。如果使用方法引用，也是同样可以根据上下文进行推导。方法引用是Lambda的孪生兄弟。</li>
</ul>
</li>
<li><p>子主题 7</p>
</li>
<li>子主题 8</li>
</ul>
<h3 id="15-引用类方法"><a href="#15-引用类方法" class="headerlink" title="15_引用类方法"></a>15_引用类方法</h3><ul>
<li><p>常见的引用方式：</p>
<ul>
<li>引用类方法</li>
<li>引用对象的实例方法</li>
<li>引用类的构造方法</li>
<li>引用构造器</li>
</ul>
</li>
<li><p>引用类方法，其实就是引用类的静态方法。</p>
<ul>
<li>格式：类名::静态方法</li>
<li>范例：Integer::parseInt</li>
<li>Integer类的方法：public static int parseInt(String s) 将此String转换为int类型数据</li>
</ul>
</li>
<li><p>练习描述：</p>
<ul>
<li><p>定义一个接口(Converter)，里面定义一个抽象方法。</p>
<ul>
<li>int convert(String s);</li>
</ul>
</li>
<li><p>定义一个测试类(ConverterDemo)，在测试类中提供两个方法。</p>
<ul>
<li>一个方法是：useConverter(Converter c)</li>
<li>一个方法是主方法，在主方法中调用useConverter方法</li>
</ul>
</li>
<li><p>使用说明：Lambda表达式被类方法替代的时候，它的形式参数全部传递给静态方法作为参数。</p>
</li>
</ul>
</li>
</ul>
<h3 id="16-引用对象的实例方法"><a href="#16-引用对象的实例方法" class="headerlink" title="16_引用对象的实例方法"></a>16_引用对象的实例方法</h3><ul>
<li><p>引用对象的实例方法，其实就引用类中的成员方法。</p>
<ul>
<li>格式：对象::成员方法</li>
<li>范例：”HelloWorld”::toUpperCase</li>
<li>String类中的方法：public String toUpperCase() 将此String所有字符转换为大写。</li>
</ul>
</li>
<li><p>练习描述：</p>
<ul>
<li>定义一个类(PrintString)，里面定义一个方法。</li>
<li>public void printUpper(String s)：把字符串参数变成大写的数据，然后在控制台输出。</li>
<li><p>定义一个接口(Printer)，里面定义一个抽象方法。</p>
<ul>
<li>void printUpperCase(String s)</li>
</ul>
</li>
<li><p>定义一个测试类(PrinterDemo)，在测试类中提供两个方法。</p>
<ul>
<li>一个方法是：usePrinter(Printer p)</li>
</ul>
</li>
<li><p>一个方法是主方法，在主方法中调用usePrinter方法。</p>
</li>
</ul>
</li>
<li><p>使用说明：Lambda表达式被对象的实例方法替代的时候，它的形式参数全部传递给该方法作为参数。</p>
</li>
</ul>
<h3 id="17-引用类的实例方法"><a href="#17-引用类的实例方法" class="headerlink" title="17_引用类的实例方法"></a>17_引用类的实例方法</h3><ul>
<li><p>引用类的实例方法，其实就是引用类中的成员方法。</p>
<ul>
<li>格式：类名::成员方法</li>
<li>范例：String::substring</li>
</ul>
</li>
<li><p>String类中的方法：public String substring(int beginIndex,int endIndex)</p>
</li>
<li>从beginIndex开始到endIndex结束，截取字符串。返回一个子串，子串的长度为endIndex-beginIndex。</li>
<li><p>练习描述：</p>
<ul>
<li><p>定义一个接口(MyString)，里面定义一个抽象方法：</p>
<ul>
<li>String mySubString(String s,int x,int y);</li>
</ul>
</li>
<li><p>定义一个测试类(MyStringDemo)，在测试类中提供两个方法：</p>
<ul>
<li>一个方法是：useMyString(MyString my)</li>
<li>一个方法是主方法，在主方法中调用useMyString方法</li>
</ul>
</li>
</ul>
</li>
<li><p>使用说明：Lambda表达式被类的实例方法替代的时候，第一个参数作为调用者，后面的参数全部传递给该方法作为参数。</p>
</li>
</ul>
<h3 id="18-引用构造器"><a href="#18-引用构造器" class="headerlink" title="18_引用构造器"></a>18_引用构造器</h3><ul>
<li><p>引用构造器，其实就是引用构造方法。</p>
<ul>
<li>格式：类名::new</li>
<li>范例：Student::new</li>
</ul>
</li>
<li><p>练习描述：</p>
<ul>
<li><p>定义一个类(Student)，里面有两个成员变量(name,age)</p>
<ul>
<li>并提供无参构造方法和带参构造方法，以及成员变量对应的get和set方法。</li>
</ul>
</li>
<li><p>定义一个接口(StudentBuilder)，里面定义一个抽象方法：</p>
<ul>
<li>Student build(String name,int age);</li>
</ul>
</li>
<li><p>定义一个测试类(StudentDemo)，在测试类中提供两个方法：</p>
<ul>
<li>一个方法是：useStudentBuilder(StudentBuilder s)</li>
<li>一个方法是主方法，在主方法中调用useStudentBuilder方法</li>
</ul>
</li>
</ul>
</li>
<li><p>使用说明：Lambda表达式被构造器替代的时候，它的形式参数全部传递给构造器作为参数。</p>
</li>
</ul>

      
    </div>
    <footer class="article-footer">
      <a data-url="https://goofyer.gitee.io/notes-on-computer-expertise/2021/12/20/Java/%E7%AC%AC%E5%8D%81%E7%AB%A0%20Lambda%E8%A1%A8%E8%BE%BE%E5%BC%8F/" data-id="cl403sxrf001zf8vu831c987v" data-title="" class="article-share-link">Share</a>
      
      
      
    </footer>
  </div>
  
</article>



  


  <nav id="page-nav">
    
    <a class="extend prev" rel="prev" href="/notes-on-computer-expertise/page/8/">&laquo; Prev</a><a class="page-number" href="/notes-on-computer-expertise/">1</a><span class="space">&hellip;</span><a class="page-number" href="/notes-on-computer-expertise/page/7/">7</a><a class="page-number" href="/notes-on-computer-expertise/page/8/">8</a><span class="page-number current">9</span><a class="page-number" href="/notes-on-computer-expertise/page/10/">10</a><a class="page-number" href="/notes-on-computer-expertise/page/11/">11</a><span class="space">&hellip;</span><a class="page-number" href="/notes-on-computer-expertise/page/14/">14</a><a class="extend next" rel="next" href="/notes-on-computer-expertise/page/10/">Next &raquo;</a>
  </nav>

</section>
        
          <aside id="sidebar">
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Categories</h3>
    <div class="widget">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/C-%E5%B7%A5%E5%85%B7/">C#工具</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/C-%E5%B7%A5%E5%85%B7/">C++工具</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/Mysql/">Mysql</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/blender/">blender</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/linux/">linux</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/manim/">manim</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/spring/">spring</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/vba%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C/">vba基础操作</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E5%88%9B%E9%80%A0%E6%A8%A1%E5%BC%8F/">创造模式</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/">操作系统</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/">操作系统基础知识</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%BC%80%E5%8F%91/">操作系统开发</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%95%B0%E5%AD%A6/">数学</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/">数据结构</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/">数据结构基础知识</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%A8%A1%E6%9D%BF/">模板</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/">深度学习</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E8%8B%B1%E8%AF%AD/">英语</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E8%99%9A%E5%B9%BB4/">虚幻4</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/">计算机组成原理</a></li><li class="category-list-item"><a class="category-list-link" href="/notes-on-computer-expertise/categories/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/">计算机网络</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/notes-on-computer-expertise/tags/C/" rel="tag">C++</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/notes-on-computer-expertise/tags/C/" style="font-size: 10px;">C++</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2022/05/">May 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2022/03/">March 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2022/02/">February 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2022/01/">January 2022</a></li><li class="archive-list-item"><a class="archive-list-link" href="/notes-on-computer-expertise/archives/2021/12/">December 2021</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/31/vue/%E5%89%8D%E7%AB%AF%E6%A1%86%E6%9E%B6%E9%AA%8C%E8%AF%81%E7%A0%81%E6%97%A0%E6%B3%95%E6%98%BE%E7%A4%BA/">(no title)</a>
          </li>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/26/%E6%95%B0%E6%8D%AE%E5%BA%93/navicat%E5%AE%89%E8%A3%85/">(no title)</a>
          </li>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/25/%E8%99%9A%E5%B9%BB4%E5%BC%95%E6%93%8E%E5%BC%80%E5%8F%91/%E8%99%9A%E5%B9%BB%E5%9B%9B%20mod%E5%88%B6%E4%BD%9C/">(no title)</a>
          </li>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/23/python/python%E6%89%B9%E9%87%8F%E7%94%9F%E6%88%90%E6%95%B0%E6%8D%AE/">(no title)</a>
          </li>
        
          <li>
            <a href="/notes-on-computer-expertise/2022/05/23/vba%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C%E7%AC%94%E8%AE%B0/EXCEL%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B/">(no title)</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      
      &copy; 2022 John Doe<br>
      Powered by <a href="https://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>

    </div>
    <nav id="mobile-nav">
  
    <a href="/notes-on-computer-expertise/" class="mobile-nav-link">Home</a>
  
    <a href="/notes-on-computer-expertise/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    


<script src="/notes-on-computer-expertise/js/jquery-3.4.1.min.js"></script>



  
<script src="/notes-on-computer-expertise/fancybox/jquery.fancybox.min.js"></script>




<script src="/notes-on-computer-expertise/js/script.js"></script>





  </div>
<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
        tex2jax: {
            inlineMath: [ ["$","$"], ["\\(","\\)"] ],
            skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code'],
            processEscapes: true
        }
    });
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax();
        for (var i = 0; i < all.length; ++i)
            all[i].SourceElement().parentNode.className += ' has-jax';
    });
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML"></script>
</body>
</html>